メインコンテンツへスキップ
見出し画像

ServiceNowのポータル画面1枚は何でできている? sp_portalからsp_widgetまで実物を1つたどる


    ポータルの並びを変えたいのに、sp_portal・sp_page・sp_widgetのどれを開けば画面のどこが変わるのか、名前だけでは見当がつきません。ServiceNowのポータル画面は、ポータル・ページ・枠・配置・部品という7段のレコードが参照でつながってできています。Zurich PDIでEmployee Centerのホーム画面を実際に開き、検索欄やタイルの1つずつがどのレコードに対応するかを、sp_portalからsp_widgetまで最後までたどりました。

    検証環境:Zurich PDI / OOTB / 2026-08-09 確認


    結論:画面1枚は7段のレコードが入れ子になっている

    • 利用者が見る1画面は、sp_portal → sp_page → sp_container → sp_row → sp_column → sp_instance → sp_widgetという7段のレコードが参照でつながってできています。

    • Employee Centerのホーム画面を実際に最後まで開くと、この1ページだけでcontainerが2件・rowが2件・columnが3件・instanceが6件でした。全体では、containerが209件・rowが260件・columnが411件・instanceが483件登録されています。

    • 画面に見える「Quick Links」のような枠は、置き場所と表示名を決めるsp_instanceと、HTML・CSS・スクリプトの中身を作るsp_widgetという別々のレコードの組み合わせです。


    画像

    この画面をレコード側からたどると、次の図になります。


    画像

    図の色は4つの意味に固定しています。濃紺は起点になるURL(sp_portal)、緑は画面の骨組み(sp_page〜sp_column)です。橙はこのページで実際に置かれた配置(sp_instance)、水色はその配置が参照する部品定義(sp_widget)です。

    読み方は上から下へ一直線です。esc(Employee Center)のsp_portalレコードは、homepageフィールドで「Employee Center Homepage」というsp_pageを指しています。このページの下に2件のsp_container、その下に合わせて2件のsp_row、3件のsp_column、そして6件のsp_instanceがぶら下がっていました。sp_instanceはsp_columnとsp_widgetの両方を参照するレコードで、ここで初めて「どの部品を、どこに置くか」が決まります。

    画面の場所と、そのレコードの対応は次のとおりでした。

    画面で見える場所        sp_instanceのtitle   sp_widgetのname   置き場所
    -----------------------------------------------------------------------
    検索欄(最上部)        (空欄)             Homepage Search   container1・row・column
    Quick links の3タイル   Quick Links          Quick Links       container2・column1・1番目
    Popular topics          Popular Topics       Popular Topics    container2・column1・2番目
    画面をスクロールした先  Recommended for you  Relevant for you  container2・column1・3番目
    My active items         My Items             My Items          container2・column2・1番目
    My favorites            Favorites            Your Favorites    container2・column2・2番目

    検索欄だけはtitleが空欄でした。widget側が検索ボックスをそのまま描くため、見出しを別に持たない部品もある、ということが分かります。


    Service Portal(サービスポータル)とは何か

    Service Portal(サービスポータル)は、ServiceNowの利用者(社員やエンドユーザー)向けの画面を提供する仕組みです。カタログから申請したり、ナレッジを検索したり、申請状況を確認したりする「使う側の画面」を、管理画面とは別に作れます。

    Service Portalそのものの概要は、公式ドキュメントのService Portalでも説明されています。

    この画面は1枚のHTMLではなく、複数のテーブルのレコードの組み合わせでできています。ポータルそのものはsp_portal、画面の単位はsp_page、画面の中の部品はsp_widgetというように、役割ごとにテーブルが分かれる作りです。「画面を直す」というのは、実質的には「どのテーブルのどのレコードを直すか」という話になります。


    画面の入口はsp_portal:なぜ既定はEmployee Centerか

    sp_portalは、URLの入口を定義するテーブルです。今回のPDIでは9件登録されていました。

    OOTBに入っている9つのポータル

    Title                           url_suffix  既定
    ------------------------------------------------
    Employee Center                 esc         ○
    Service Portal                  sp
    Knowledge Portal                kb
    CAB Workbench                   cab
    Mobile Employee Service Portal  mesp
    Benchmarks                      benchmarks
    Performance Analyzer            perf
    SP Configuration                sp_config
    Service Workspace Portal        swp


    画像

    9件のうち、defaultがtrue(既定)なのはEmployee Center(url_suffix=esc)だけです。sp_portalはhomepageフィールドで入口ページ(sp_page)を、themeフィールドで見た目(sp_theme)を指します。login_page・notfound_page(404)・sc_catalog_pageなども、いずれもsp_pageを参照するフィールドです。ログイン画面や404画面も、それぞれ別のページレコードとして差し替えられる構造でした。

    sp_page自体は119件ありましたが、public=true(未ログインでも見られる)はわずか5件でした。Employee Centerのホームを含め、大半のページはログイン後に見る前提で作られています。

    Employee Centerのthemeフィールドは、「Employee Center Coral Theme」というsp_themeレコードを指していました。テーマは全体で17件です。配色やヘッダ・フッタの枠は、このsp_theme側で決まります。


    テーブルの継承は浅い:8つとも sys_metadata 直下

    sp_portalからsp_themeまでの8テーブルは、深い業務継承を持ちません。


    画像

    incidentやcmdb_ciのようなテーブルは、taskやcmdb_ciを頂点とする業務的な継承階層を持ちます。Service Portal側の8テーブルは、いずれもsuper_classがsys_metadata(Application File)でした。対象はsp_portal・sp_page・sp_container・sp_row・sp_column・sp_instance・sp_widget・sp_themeです。業務的な親子関係の積み上げ構造ではありません。すべてが「アプリの構成ファイル」として横並びになっています。

    だから、ページとコンテナ、列と配置がどうつながっているかは、各テーブルの参照(Reference)フィールドで表されます。参照フィールドで親をたどる、という読み方がこのファミリーの基本です。参照はすべて上向きです。

    テーブル定義は、次のURLで確認できます(先頭の<YourInstance>は自分のインスタンスに置き換えてください)。

    https://<YourInstance>/sys_db_object_list.do?sysparm_query=nameSTARTSWITHsp_


    画像

    枠組み(container→row→column)はどの参照でつながるか

    画面の段組みは、sp_container→sp_row→sp_columnという3段で表されます。それぞれの参照フィールドは、次の向きで上をたどります。

    • sp_containerのsp_pageフィールド → sp_page(コンテナはどのページに属するか)

    • sp_rowのsp_containerフィールド → sp_container(行はどのコンテナに属するか)

    • sp_columnのsp_rowフィールド → sp_row(列はどの行に属するか)

    • sp_instanceのsp_columnフィールド → sp_column(配置はどの列に置かれるか)

    • sp_instanceのsp_widgetフィールド → sp_widget(配置がどの部品本体を指すか)

    各テーブルはorderフィールドを持ち、同じ親の中での並び順を決めます。画面の上下・左右の並びを変えたいときは、container・row・column・instanceのorderを見ることになります。


    画像

    全体の件数で見ると、sp_containerが209件・sp_rowが260件・sp_columnが411件・sp_instanceが483件です。1つのページに複数のコンテナ、その中に複数の行・列・配置が入るため、下の段ほどレコード数が多くなる関係が全体でも観察できます。Employee Centerのホームは、そのうちの2件・2件・3件・6件を使っている1ページということになります。


    配置(sp_instance)と部品定義(sp_widget)はなぜ別テーブルか

    呼び名が紛らわしい2つです。つまずきやすいのが、「画面に置かれた部品」と「部品の定義」が別テーブルである点です。

    • sp_widget(部品本体) … 部品の定義そのもの。1つのsp_widgetは、多くのページで何度でも使い回せます。全体で295件です。

    • sp_instance(配置) … 「その部品を、この列に、このタイトルで、このオプション値で置く」という1回ぶんの配置。全体で483件です。


    画像

    先ほどの表のとおり、Employee Centerのホームでは6件のsp_instanceが、6種類のsp_widgetを1件ずつ呼び出していました。内訳はHomepage Search・Quick Links・Popular Topics・Relevant for you・My Items・Your Favoritesです。同じsp_widgetを、別のページで別のオプション値で置けば、見え方を変えられます。

    sp_instanceはsp_widgetで部品本体を、sp_columnで置き場所を参照します。加えてtitleやwidget_parameters(Additional options, JSON format)に、その配置だけのタイトルやオプション値を持つ設計です。「この部品そのものを直したい(全ポータル共通で)」ならsp_widgetを見て、「この場所のこの部品だけ設定を変えたい」ならsp_instanceを見る、という使い分けになります。


    部品本体(sp_widget)は4つの中身を1レコードに持つ

    中身は多彩です。sp_widgetは、HTML・CSS・クライアント・サーバの4つの中身を1レコードにまとめて持つ部品です。

    Widgetが画面を組み立てる再利用部品であることは、公式ドキュメントのService Portal widgets(Using portal widgets)でも説明されています。


    画像


    画像

    sp_widgetの固有フィールドは21あり、中心になるのは次の4つです。

    sp_widgetの主な固有フィールド

    Field          Label               Type              説明
    ---------------------------------------------------------
    template       Body HTML template  html_template     画面に出すHTMLテンプレート
    css            CSS                 css               このWidgetのCSS
    client_script  Client controller   script            ブラウザ側スクリプト(AngularJS controller)
    script         Server script       script            サーバ側スクリプト(dataオブジェクトを作る)
    link           Link                script            link関数
    option_schema  Option schema       json              配置ごとに渡せる項目の定義(JSON)
    id             ID                  string            Widgetの識別子(空欄も多い)
    name           Name                translated_field  表示名(必須)
    public         Public              boolean           未ログインでも使えるか
    category       Category            string            分類(既定custom)
    data_table     Data table          table_name        配置データの格納先(既定sp_instance)
    demo_data      Demo data           json              プレビュー用のサンプルデータ

    public=trueのWidgetは295件中95件でした。残りは、roleやページ側のアクセス権によって表示が絞られる部品です。

    全フィールドは、次のURLで一覧できます。

    https://<YourInstance>/sys_dictionary_list.do?sysparm_query=name=sp_widget^elementISNOTEMPTY


    画像

    実機で気づいたこと

    気づいたことは3つあります。

    画面の見出しとsp_instance.titleが一致しない例がありました。 「My active items」の枠は、instance側のtitleを見ると「My Items」でした。「My favorites」の枠もtitleは「Favorites」です。widget側のname(sp_widget.name)まで見ると、instanceのtitleとも揃っていない例があります。「Recommended for you」というinstanceタイトルに対応するwidgetのnameは「Relevant for you」でした。instance.titleとwidget.nameは別々の自由入力欄で、両者を一致させる仕組みはありません。widget側が見出し文字列をテンプレートに直接書き込んでいる場合、instance.titleは補助的な値にとどまっていると考えられます。ここは推測です。

    上部のナビゲーションとバナーは、この入れ子の外側にありました。 画面最上部の赤いバナーとロゴ・メニューの行は、ここまでたどったsp_container以下の構造には含まれていません。ポータルのテーマ(sp_theme)が持つheaderフィールドは、sp_header_footerというテーブルを指します。このテーブルの固有フィールドは、Static(固定表示にするかどうか)の1つだけでした。container・row・column・instanceのような入れ子を、header/footer側は持っていません。画面上部の表示を疑うときにsp_instance一覧をいくら探しても見つからない理由は、ここにあります。ヘッダーの中身が実際にどう組み立てられているかまでは、今回は確認していません。

    6月に確認したときと比べて、件数が全体的に増えていました。 sp_pageは116件から119件、sp_containerは203件から209件、sp_instanceは478件から483件に増えています。カスタマイズを加えていないPDIでも、パッチの適用や関連アプリの更新でOOTBの件数は変わるものだと考えたほうがよさそうです。同じ環境を開いても、時期によってここに書いた数字とは違う値が出ることがあります。


    実務では何に使えるか:直したい場所から逆算する

    ここまでの構造を、読者の疑問「どこを触る?」に対応づけると次のようになります。


    画像
    • 入口のURL・既定ページ・テーマを変えたい → sp_portal

    • ページ単位の構成や公開範囲(public / roles)を変えたい → sp_page

    • 部品の並び・段組み(枠)を変えたい → sp_container / sp_row / sp_columnのorder

    • どの部品をどこに置くか・その配置ごとの設定値を変えたい → sp_instance(widget_parameters)

    • 部品そのものの表示内容やロジックを変えたい → sp_widget(template / css / client_script / script)

    • 配色やヘッダ・フッタの見た目を変えたい → sp_theme

    たとえば「Quick Linksのタイルを1枚増やしたい」という依頼なら、答えはsp_instanceの追加です。sp_widgetやsp_containerまで触る必要はありません。逆に「検索欄のロジックそのものを変えたい」なら、答えはsp_widget側のscriptです。

    同じ「画面を直す」でも、影響範囲は段によって違います。sp_widgetを直すと、その部品を使う全ポータル・全配置に影響します。sp_instanceの設定は、その配置だけが対象です。今回のEmployee Centerホームのように、1つのwidgetが1ページで1回しか使われていなければ、影響は小さくて済みます。複数ページで使い回されているwidgetを直すときほど、影響範囲を先に洗い出す必要があります。


    よくある質問

    Q1. sp_instanceのtitleが空欄のままでも問題ありませんか

    空欄のままで問題ありません。今回の検索欄のように、widget側がタイトル表示を前提にしていない部品では、titleを設定しない使い方がふつうです。逆に、同じ種類のwidgetを複数並べる場面では、titleを入れておいたほうが管理しやすくなります。

    Q2. 1つのcontainerに複数のrowを持たせることはできますか

    できます。今回たどった2件のcontainerは、たまたまどちらもrowが1件だけでした。rowのsp_containerフィールドは、同じcontainerを指す複数レコードを許容する参照です。段組みを縦に増やしたいときは、同じcontainerの下にrowを追加する形になります。

    Q3. 自分のポータルで同じように1画面ぶんの構造を調べるにはどこから見ればいいですか

    まずsp_portal一覧でhomepageの値を確認し、そのsp_pageに紐づくsp_containerを絞り込みます。あとはcontainer→row→column→instanceの順に、それぞれ親のレコードで絞り込めば、今回と同じ手順でページ1枚ぶんの構造をたどれます。


    さらに詳しく知りたい人へ


    用語

    • PDI … Personal Developer Instance(無料の検証用インスタンス)

    • OOTB … Out of the Box(初期設定のまま)

    • Service Portal … 利用者向けの画面を提供する仕組み

    • sp_instance(配置) … Widgetを画面のどこに、どんな設定で置くかを表すレコード

    • sp_widget(部品本体) … 画面の部品本体(HTML/CSS/Client/Serverを持つ)

    • sys_metadata(Application File) … アプリの構成ファイルを表す基底テーブル

    実機で調べるときに開いたURL

    • sp_portal_list.do … ポータル一覧

    • sp_page_list.do … ページ一覧

    • sp_container_list.do / sp_row_list.do / sp_column_list.do … レイアウト

    • sp_instance_list.do … 配置一覧

    • sp_widget_list.do … Widget定義一覧

    • sys_db_object_list.do?sysparm_query=nameSTARTSWITHsp_ … テーブル定義(sp_*)

    • sys_dictionary_list.do?sysparm_query=name=sp_widget^elementISNOTEMPTY … sp_widgetのフィールド一覧


    参考リンク

    検証環境と未検証範囲

    確認した範囲(PDI/Zurich/2026-08-09確認のOOTBで取得):

    • sp_portal/sp_page/sp_container/sp_row/sp_column/sp_instance/sp_widget/sp_themeの継承(すべてsys_metadata直下)

    • 構造を作る参照フィールドの向きとorderによる並び順

    • 各テーブルの固有フィールド数、sp_widgetの4要素(template/css/client_script/script)

    • 各テーブルの全体件数と、Employee Centerホーム1ページ内の件数(container 2/row 2/column 3/instance 6)

    • OOTBポータル一覧(9件・既定はesc)、sp_pageのpublic件数(5件)、sp_widgetのpublic件数(95件)

    確認していない範囲:

    • Widgetの描画やAngularProviderなど実行時の挙動、$sp / GlideSPScriptableなどServer Script APIの動作

    • sp_header_footerが実際にどう内容を持ち描画されるかの詳細(Static以外のフィールドは確認できていない)

    • Service PortalとNext Experience(UI Builder / sys_ux_*系)の関係詳細、各ポータルのACL・ロールによる可視範囲

    件数は2026-08-09時点の値です。本番環境やカスタマイズ済みの環境では、ポータル構成・フィールド・件数の内容が異なります。

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ