Skip to main content

你的第一個 Shopify 應用程式

在這一課中,你將從零開始到在開發商店上執行一個 Shopify 應用程式。我們將使用 Shopify CLI 來搭建專案、了解檔案結構、啟動開發伺服器,然後使用 Claude Code 建構你的第一個功能。

使用 shopify app init 搭建專案

Shopify CLI 會產生一個完整的應用程式專案,其中已配置好驗證、資料庫和 UI。執行以下命令:

# Create a new Shopify app
cd ~/shopify-projects
shopify app init

# The CLI will prompt you:
# ? Your app project name: masterclass-app
# ? Get started building your app:
# > Start with Remix (recommended)
# Start with a blank extension-only app
# Start with a template

選擇 Start with Remix —— 這是 Shopify 推薦的框架,也是我們在整個課程中使用的框架。

# After scaffolding completes
cd masterclass-app
為什麼選擇 Remix?

Shopify 選擇 Remix 作為推薦的應用程式框架,因為它的伺服器端渲染模型、巢狀路由和優秀的資料載入模式。Remix 的 actions 和 loaders 自然地對應到 Shopify 的 OAuth 流程和 API 呼叫。Shopify Remix 範本包含現成的驗證、session 管理和 App Bridge 整合。

了解專案結構

搭建好的專案有一個特定的結構,了解它很重要。每個目錄都有明確的用途:

masterclass-app/
├── app/ # Remix application
│ ├── routes/ # Page routes (file-based routing)
│ │ ├── app._index.jsx # Main app page (after auth)
│ │ ├── app.jsx # App layout with nav
│ │ ├── auth.$.jsx # OAuth callback handler
│ │ ├── auth.login/ # Login page
│ │ │ ├── route.jsx
│ │ │ └── login.css
│ │ └── webhooks.jsx # Webhook handler
│ ├── shopify.server.js # Shopify API client setup
│ ├── db.server.js # Database connection (SQLite)
│ └── entry.server.jsx # Remix server entry
├── extensions/ # Shopify extensions (UI, Functions, etc.)
├── prisma/
│ └── schema.prisma # Database schema
├── public/ # Static assets
├── shopify.app.toml # App configuration
├── shopify.web.toml # Web server configuration
├── package.json
├── remix.config.js
└── .env # Environment variables (auto-generated)

關鍵檔案說明

shopify.app.toml —— 應用程式清單。它定義了你的應用程式名稱、scopes(權限)和擴充功能配置:

name = "masterclass-app"
client_id = "your-client-id"
application_url = "https://your-tunnel.trycloudflare.com"
embedded = true

[access_scopes]
scopes = "write_products,read_orders"

[webhooks]
api_version = "2026-04"

app/shopify.server.js —— Shopify API 用戶端。此檔案設定驗證並提供進行 API 呼叫的方法:

import "@shopify/shopify-app-remix/adapters/node";
import {
ApiVersion,
AppDistribution,
shopifyApp,
} from "@shopify/shopify-app-remix/server";
import { PrismaSessionStorage } from "@shopify/shopify-app-session-storage-prisma";
import prisma from "./db.server";

const shopify = shopifyApp({
apiKey: process.env.SHOPIFY_API_KEY,
apiSecretKey: process.env.SHOPIFY_API_SECRET || "",
apiVersion: ApiVersion.April26,
scopes: process.env.SCOPES?.split(","),
appUrl: process.env.SHOPIFY_APP_URL || "",
authPathPrefix: "/auth",
sessionStorage: new PrismaSessionStorage(prisma),
distribution: AppDistribution.AppStore,
future: {
unstable_newEmbeddedAuthStrategy: true,
},
});

export default shopify;
export const apiVersion = ApiVersion.April26;
export const addDocumentResponseHeaders = shopify.addDocumentResponseHeaders;
export const authenticate = shopify.authenticate;
export const unauthenticated = shopify.unauthenticated;
export const login = shopify.login;
export const registerWebhooks = shopify.registerWebhooks;
export const sessionStorage = shopify.sessionStorage;

app/routes/app._index.jsx —— 你的應用程式主頁面,作為嵌入式應用程式渲染在 Shopify Admin 內。

執行開發伺服器

使用 Shopify CLI dev 命令啟動你的應用程式:

shopify app dev

這個單一命令做了大量的工作:

CLI 將會:

  1. 啟動 Remix 開發伺服器,在 localhost:3000
  2. 建立 Cloudflare tunnel,提供 HTTPS 存取
  3. 更新你的應用程式 URL,在 Partner Dashboard 中
  4. 開啟你的瀏覽器,將應用程式安裝到你的開發商店
首次執行需要較長時間

首次執行時,CLI 會建立資料庫表格、產生 OAuth 憑證,並設定 tunnel。後續執行會快得多。

安裝到開發商店

當 CLI 開啟你的瀏覽器時,你會看到一個 Shopify 授權畫面。點擊 Install app 來授予請求的權限。安裝完成後,你的應用程式主頁面會嵌入在 Shopify Admin 中顯示。

你應該會看到一個使用 Shopify Polaris UI 的頁面,上面寫著「Nice work on building a Shopify app」以及一些範例內容。

使用 Claude Code 建構你的第一個功能

現在是令人興奮的部分 —— 使用 Claude Code 建構一個真正的功能。我們將新增一個產品計數儀表板,顯示商店中產品的總數及其狀態分佈。

在你的專案目錄中開啟 Claude Code:

cd ~/shopify-projects/masterclass-app
claude

給 Claude Code 這個提示:

Update the main app page (app/routes/app._index.jsx) to show a product
dashboard. Use the Shopify Admin GraphQL API to fetch the total number
of products and break them down by status (active, draft, archived).
Display the data using Polaris Cards and Layout components. Include a
loading state.

Claude Code 將會:

  1. 閱讀現有的 app._index.jsx 檔案以了解目前的結構
  2. 編寫一個 Remix loader 函式來呼叫 Shopify Admin API
  3. 使用 GraphQL 查詢來取得各狀態的產品數量
  4. 更新 JSX 來渲染 Polaris CardLayoutText 元件
  5. 新增載入和錯誤狀態

結果程式碼如下:

import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import {
Page,
Layout,
Card,
BlockStack,
Text,
InlineGrid,
} from "@shopify/polaris";
import { authenticate } from "../shopify.server";

export const loader = async ({ request }) => {
const { admin } = await authenticate.admin(request);

const response = await admin.graphql(`
{
activeCount: productsCount(query: "status:active") {
count
}
draftCount: productsCount(query: "status:draft") {
count
}
archivedCount: productsCount(query: "status:archived") {
count
}
totalCount: productsCount {
count
}
}
`);

const data = await response.json();

return json({
products: {
total: data.data.totalCount.count,
active: data.data.activeCount.count,
draft: data.data.draftCount.count,
archived: data.data.archivedCount.count,
},
});
};

export default function Index() {
const { products } = useLoaderData();

return (
<Page title="Product Dashboard">
<Layout>
<Layout.Section>
<InlineGrid columns={4} gap="400">
<Card>
<BlockStack gap="200">
<Text variant="headingSm">Total Products</Text>
<Text variant="heading2xl">{products.total}</Text>
</BlockStack>
</Card>
<Card>
<BlockStack gap="200">
<Text variant="headingSm">Active</Text>
<Text variant="heading2xl" tone="success">
{products.active}
</Text>
</BlockStack>
</Card>
<Card>
<BlockStack gap="200">
<Text variant="headingSm">Draft</Text>
<Text variant="heading2xl" tone="caution">
{products.draft}
</Text>
</BlockStack>
</Card>
<Card>
<BlockStack gap="200">
<Text variant="headingSm">Archived</Text>
<Text variant="heading2xl" tone="subdued">
{products.archived}
</Text>
</BlockStack>
</Card>
</InlineGrid>
</Layout.Section>
</Layout>
</Page>
);
}

儲存檔案並檢查你的瀏覽器 —— Remix 會自動熱重載,所以你應該會看到產品儀表板出現。

Agentic 的優勢

注意剛才發生了什麼。你用純英文描述了一個功能,Claude Code 就寫出了 GraphQL 查詢、Remix loader 和 Polaris UI。它知道要使用 authenticate.admin(request),因為它讀取了你現有的 shopify.server.js 檔案。它知道要使用 productsCount,因為它了解 Shopify Admin API。這就是 Agentic Coding 的實際運作。

檢查點

在繼續之前,請驗證:

  • shopify app dev 啟動時沒有錯誤
  • 你的應用程式已安裝在開發商店上
  • 產品儀表板顯示了商店的真實資料
  • 你已成功使用 Claude Code 修改了你的應用程式
常見問題

「App not loaded」錯誤:確保你使用的是 Cloudflare tunnel URL,而不是 localhost。tunnel 由 shopify app dev 自動建立。

「Access denied」錯誤:檢查你在 shopify.app.toml 中的應用程式 scopes 是否包含 read_products。執行 shopify app dev --reset 來重新驗證。

產品數量為空:如果你的開發商店沒有產品,請前往 Shopify Admin 並點擊「Add product」來建立一些測試產品,或使用批量匯入功能。

你學到了什麼

在這一課中你:

  1. 使用 Shopify CLI 搭建了一個 Shopify Remix 應用程式
  2. 了解了專案結構和關鍵配置檔案
  3. 執行了具有 tunneling 和熱重載的開發伺服器
  4. 在開發商店上安裝了應用程式
  5. 使用 Claude Code 建構了一個產品儀表板功能

在下一課中,我們將探索 Shopify Partner 生態系統,了解 Shopify 開發的商業面向。