勇者(さかもっちゃん) 弊社若手エンジニアがShopifyでRPG風サイトを制作中!遊んで行ってね!
MORE

BLOG

Shopify PolarisでShopify埋め込みアプリ管理画面を作成しよう②|Index table・Collapsible 活用編

  • Shopify
  • Shopify Polaris
  • Shopify アプリ
  • UI/UX
  • デザイン
  • 初心者向け
  • 埋め込みアプリ
  • 導入方法
  • 開発
25.05.27

関連記事

1.はじめに

1.1 記事について

本記事は「Shopify Polarisを使って埋め込みアプリのUIを作ってみたい!」という方向けの実践シリーズ第2弾です。

今回は、以下のような「よりリッチで整理された管理画面」を実装していきます。

・「Index table」で商品を一覧表示する

・「Collapsible」で折り畳み式の説明を表示する

コードが初めての方でも安心して読み進められるよう、画像付きでステップごとに解説していきます!前回(第1弾)で以下の埋め込みアプリ管理画面を作った方は、今回の内容を追加するだけでOK!

Shopify PolarisでShopify埋め込みアプリ管理画面を作成しよう②|Index table・Collapsible 活用編 - 株式会社テックディレクション
第1弾で作成可能なShopify埋め込みアプリ管理画面

第1弾の記事はこちらです。まだご覧になっていない方は、併せてチェックしてみてください👇!

Shopify PolarisでShopify埋め込みアプリ管理画面を作成しよう① – 株式会社テックディレクション

1.2 対象読者

本記事は以下ような方に向けて記載しております。

・ Shopify Polarisのコンポーネントを使って見やすくて操作しやすいUIを作りたい方

・ Shopify埋め込みアプリ管理画面をもっと便利にカスタマイズしたい方

・ 初心者だけど、実践を通じて少しずつコードに慣れていきたい方

1.3 所要時間

この記事は約20分で読み終えることができます。

コードのコピペで動かしながら学ぶ方は、実装時間も含めて30分程度です。

2.完成イメージ

今回ご紹介する埋め込みアプリ管理画面の完成イメージは以下の通りです。

Shopify PolarisでShopify埋め込みアプリ管理画面を作成しよう②|Index table・Collapsible 活用編 - 株式会社テックディレクション
応用編ページを追加して、開閉する説明と商品一覧を作成します。

3.今回使うShopify Polarisコンポーネント

3.1 Index table

大量のデータを「見やすく一覧表示」できる便利なテーブルコンポーネントです。

商品一覧や注文一覧など、EC運営では欠かせないUIを簡単に作れます。

※ 使い方が少し複雑なので、実装手順はこのあと詳しく解説します!

3.2 Collapsible

クリックで内容を「折りたたみ/展開」できる機能です。

情報が多いときにスッキリ整理できて、ユーザーにやさしい画面が作れます。

import { Button, Collapsible, TextContainer } from '@shopify/polaris';
import { useState, useCallback } from 'react';

function CollapsibleExample() {
  const [open, setOpen] = useState(false);
  const toggle = useCallback(() => setOpen(o => !o), []);

  return (
    <>
      <Button onClick={toggle}>
        {open ? '閉じる' : '詳細設定を表示'}
      </Button>
      <Collapsible open={open}>
        <TextContainer>
          <p>ここに詳細設定の内容が表示されます。</p>
        </TextContainer>
      </Collapsible>
    </>
  );
}

💡 補足 このコードの意味をカンタンに解説!

const [open, setOpen] = useState(false);
const toggle = useCallback(() => setOpen(o => !o), []);

・seState(false) → 「いま開いてるかどうか」の状態を管理します。 最初は「閉じてる状態(false)」でスタート!

・setOpen() → 現在の状態(o)を反転させて、開いたり閉じたりを切り替えます。

・useCallback() → 毎回この関数を新しく作らないようにする工夫です。 例えばボタンが何度も表示されるような場合、処理が軽くなってパフォーマンスがちょっとよくなります。


次の章では、第1弾で使用したコンポーネント + 上記2つのコンポーネントを使って応用ページを実装します!

4.【実践】Shopify Polarisで管理画面を構築しよう!

それでは、前回作成した埋め込みアプリ管理画面に、新しく「応用編ページ」を追加していきましょう!

4.1 応用編ページをナビゲーションに追加しよう

①リンクを追加しよう

まずはアプリ管理画面のナビゲーションに応用編ページのリンクを追加します。

Shopify PolarisでShopify埋め込みアプリ管理画面を作成しよう②|Index table・Collapsible 活用編 - 株式会社テックディレクション

アプリ管理画面>ナビケーションに「応用編ページ」を追加します

app.tsx ファイルの内のナビゲーションメニューに、赤字の一行を追加します。

  return (
    <AppProvider isEmbeddedApp apiKey={apiKey}>
      <NavMenu>
        <Link to="/app" rel="home">Home</Link>
        <Link to="/app/additional">Additional page</Link>
        <Link to="/app/advanced">応用編ページ</Link> {/* ← この行を追加 */}
      </NavMenu>
      <Outlet />
    </AppProvider>
  );

これで「/app/advanced」URLへアクセス可能になります。 ※<NavMenu>の詳細は別記事で解説予定です。

②新しいページ用ファイルを作成

次に、応用編ページの中身を表示するファイルを作成します。

app/routes ディレクトリに以下のファイルを新規作成します。

app.advanced.tsx

このファイルが/app/advanced ページとして機能します。

これから具体的にページの中身を書いていきましょう!🌟


💡 参考 Remixファイルのルーティングについて

「RemixアプリのソースファイルがどのURLに対応しているか」気になる方は、以下のリンクを参考にしてください 🌟

ルートファイルの命名 – Remix ドキュメント 日本語版


4.2 IndexTableで一覧表示を作ろう

応用編ページ(app.advanced.tsx)に商品一覧テーブルを追加して、情報をより見やすく表示できるようにしてみましょう! Index table コンポーネントを使うことで、整ったテーブルUIを簡単に実装していきます ✨

完成イメージはこちら👇

以下のような、商品情報を整然と表示できるテーブルが完成します👇

Shopify PolarisでShopify埋め込みアプリ管理画面を作成しよう②|Index table・Collapsible 活用編 - 株式会社テックディレクション

Index tableを用いた商品一覧テーブル 実装イメージ

コピペでOK!以下のコードを app.advanced.tsx に貼り付けてください👇

import { Page, Card, IndexTable, Text, Layout } from '@shopify/polaris';

function AdvancedProductListPage() {
  // 商品データ(今回はダミーデータ)
  const products = [
    { id: '1', name: 'りんご飴一生タダ券', price: 500, stock: 10 },
    { id: '2', name: '二郎ラーメン一生タダ券', price: 1000, stock: 5 },
    { id: '3', name: '焼肉無限一生タダ券', price: 10000, stock: 20 },
  ];

  // IndexTableに必要なリソース名の設定(単数・複数)
  const resourceName = {
    singular: '商品',       // 単数形
    plural: '商品一覧',     // 複数形
  };

  return (
    <Page title="応用編ページを作成しよう!">
      <Layout>
        <Layout.Section>
          <Card>
            {/* IndexTable はリスト表示に特化したテーブルコンポーネント */}
            <IndexTable
              resourceName={resourceName}  
              itemCount={products.length}
              headings={[
                { title: '商品名' },
                { title: '価格' },
                { title: '在庫数' },
              ]}
            >
              {/* products 配列を map でループし、各商品の行を作成 */}
              {products.map(({ id, name, price, stock }, index) => (
                <IndexTable.Row
                  id={id}               // 各行のユニークID
                  key={id}              // React の key 属性
                  position={index}      // 行の位置(IndexTableのために必要)
                >
                  {/* 商品名 */}
                  <IndexTable.Cell>
                    <Text as="span">{name}</Text>
                  </IndexTable.Cell>

                  {/* 価格(¥記号を付与) */}
                  <IndexTable.Cell>
                    <Text as="span">¥{price}</Text>
                  </IndexTable.Cell>

                  {/* 在庫数(「枚」を付けて表示) */}
                  <IndexTable.Cell>
                    <Text as="span">{stock} 枚</Text>
                  </IndexTable.Cell>
                </IndexTable.Row>
              ))}
            </IndexTable>
          </Card>
        </Layout.Section>
      </Layout>
    </Page>
  );
}

export default AdvancedProductListPage;

export default AdvancedProductListPage;

💡この時点では、一覧表示の基本機能だけをシンプルに実装しています。追加機能については別記事で紹介予定です。


🔍 コードのポイント解説

① 商品データを用意

const products = [...];

今回は3件のダミーデータを配列で定義しています。実際の開発では、Shopify APIなどを使ってデータを取得するのが一般的です。


📘 Shopify APIを使ったデータ取得方法は、今後の記事で詳しく紹介します!


② IndexTableの設定

<IndexTable
  resourceName={resourceName}
  itemCount={products.length}
  headings={[...]}
>

resourceName:表示対象のリソース名(単数形と複数形)を設定します。

itemCount:表示するアイテムの数(products配列の長さ:3)を取得します。

headings:テーブルの列タイトルを指定します

.map() を使って各行を描画

products.map(({ id, name, ... }) => (
  <IndexTable.Row id={id} key={id} position={index}>

各商品の情報を .map() でループしながら、テーブルの行を生成しています。

④ 各セルの中身を <Text as="span"> で整える

<IndexTable.Cell>
  <Text as="span">{name}</Text>
</IndexTable.Cell>

コピペしたコードが埋め込みアプリ管理画面内で正しく動くことを確認しましょう!


💡 ローカル環境で埋め込みアプリ管理画面を確認する方法はこちら


上手く商品一覧UIを作成できましたでしょうか??

Polarisの真骨頂ともいえる便利機能なので、ぜひ活用していきましょう!

4.3 Collapsibleで折りたたみ機能を作ろう!

最後に、ページ冒頭に折り畳み式の説明文を実装して、画面を簡潔にわかりやすく見せましょう!Shopify Polarisが提供する Collapsible コンポーネントを使えば、簡単に開閉できるUIが作れます。ここでは、4.2 で作ったコードに追記するだけでOKです ✨

Shopify PolarisでShopify埋め込みアプリ管理画面を作成しよう②|Index table・Collapsible 活用編 - 株式会社テックディレクション
Collapsibleコンポーネントを用いた表示/表示ボタン付きの説明文UI 実装イメージ

①必要なコンポーネントを読み込もう

まずは、Polarisのコンポ―メント(Button, Collapsible, Link)とReactのフックをimport文に追加します。

import { Page, Card, IndexTable, Text, Layout, Button, Collapsible, Link } from '@shopify/polaris';
import { useState, useCallback } from 'react';  // ← 状態管理用のReactフックを追加

Button:クリックできるボタンUI

Collapsible:表示・非表示を切り替えられる領域

Link:外部リンクを表示するためのコンポーネント

useStateuseCallback:Reactの状態管理に使います

開閉用の状態を追加しよう

次に、関数コンポーネントの先頭で、「開いてるかどうか」を管理するstateを用意します👇

export default function AdvancedProductListPage() {
	const [open, setOpen] = useState(false);  // 「開いてるかどうか」を管理(初期状態は閉じてる)
	const toggleOpen = useCallback(() => setOpen((open) => !open), []);  // ボタンを押すたびに開閉を切り替える関数

この2行があることで、ボタンを押すたびに説明文の表示/非表示が切り替えられます✨

ページ内に説明エリアを追加しよう 次に、<Layout>の中に「説明文の折りたたみエリア」を追加します👇

return (
  <Page title="応用編ページを作成しよう!">
    {/* Layout は画面を複数のセクションに分割できるコンポーネント */}
    <Layout>
	    {/* ▼ここから追加! */}
      <Layout.Section>
        <Card>
          <div style={{ padding: '16px' }}>
            <Button onClick={toggleOpen}>
              {open ? '説明を隠す' : '説明を表示'}
            </Button>

            <Collapsible open={open} id="説明セクション">
              <div style={{ paddingTop: '16px' }}>
                <Text as="p" variant="bodyMd">
                  このページでは、Shopify Polarisの<strong>Index table</strong>を使って、シンプルな商品一覧を表示しています。
                  また、<strong>Collapsible</strong>を使って説明文を開閉できるようにすることで、UIの情報量をコントロールしています。
                </Text>

                <div style={{ marginTop: '12px' }}>
                  <Text as="h2" variant="headingMd">
                    Index tableとは?<br />
                  </Text>
                </div>
                <Text as="p" variant="bodyMd">
                  Shopifyアプリでのデータ一覧表示に最適な、Polarisが提供する標準テーブルコンポーネントです。
                  <br />
                  ➤{' '}
                  <Link
                    url="https://polaris.shopify.com/components/tables/index-table?example=index-table-default"
                    target="_blank"
                  >
                    Polaris公式:Index tableのドキュメント<br />
                  </Link>
                </Text>

                <div style={{ marginTop: '12px' }}>
                  <Text as="h2" variant="headingMd">
                    Collapsibleとは?<br />
                  </Text>
                </div>
                <Text as="p" variant="bodyMd">
                  説明文などを折りたたんで表示したい時に使えるPolarisのコンポーネントです。
                  <br />
                  ➤{' '}
                  <Link
                    url="https://polaris.shopify.com/components/behaviors/collapsible"
                    target="_blank"
                  >
                    Polaris公式:Collapsibleのドキュメント<br />
                  </Link>
                </Text>
              </div>
            </Collapsible>
          </div>
        </Card>
      </Layout.Section>
      {/* ▲ここまで追加! */}
      
      {/* 商品一覧エリア(4.2の内容) */}
      <Layout.Section>

これで、ボタンをクリックすると説明が開閉できるUIが完成しました!

IndexTableの前に説明を載せたいけど、見た目はスッキリ保ちたいときに便利です 💡

埋め込みアプリ管理画面を開いて、挙動を確認してみてください~✨

おつかれさまでした!以上で第2弾は完了です!

5.まとめ

今回は、Shopify Polarisの「IndexTable」と「Collapsible」コンポーネントを活用して、より実践的な埋め込み管理画面の作成方法を学びました! 本記事を通して、以下のようなUI構築ができるようになりましたね ✅

✅ 商品情報を見やすく並べた「IndexTable」で一覧表示

✅ 詳細情報をスッキリまとめられる「Collapsible」で折りたたみ機能

✅ ナビゲーションからのページ切り替えで、複数画面の管理にも対応

次回は、いよいよShopifyのAPIと連携して、商品データを取得する方法をご紹介します!IndexTable実装時、「手動で商品を定義したくないな~」と思った皆様!必見です🚀✨

お楽しみに!

著者:さかもっちゃん

弊社では、ECサイトのリプレース案件から、Shopifyカスタムアプリ開発、保守案件に至るまで、EC中心にプロジェクトの質にこだわり、お客様に笑顔になってもらえるよう日々邁進しております。

皆様からのお問い合わせ・ご相談をお待ちしております。

お問い合わせはこちら