使用令牌交换(unstable_newEmbeddedAuthStrategy)完成嵌入式应用 OAuth,而非传统整页重定向
shopify-app-starter-remix — Remix 启动器模板
作者 Ecom-Swift-LLC
基于 Remix 的嵌入式 Shopify 应用启动器,内置令牌交换 OAuth、Prisma 会话存储、三个强制 GDPR Webhook 与 Billing API 套餐门控,并附带单元测试。
看看你的网站会是什么样
浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。
全部页面与视图 3
截图用于了解视觉与布局,交互效果请以实际项目为准。
值得关注的模板亮点
从已有项目资料中,快速了解它的特点。
内置三个强制 GDPR Webhook 路由,以及卸载与权限变更等生命周期 Webhook
Prisma 会话存储默认 SQLite,只需修改 datasource 即可切换到 Postgres/MySQL/MongoDB
计费套餐门控与套餐选择界面,套餐目录集中在 app/lib/plans.ts
店铺域名归一化、套餐目录、Webhook 主题映射等逻辑配有 25 个 Vitest 用例
README 明确列出模板不做的部分,包括 GDPR 处理器仅记录不删除数据
模板详细介绍
这是一个面向 Shopify 嵌入式应用的 Remix 启动器,由 Ecom Swift LLC 维护,采用 MIT 许可。它把自定义应用开发初期常见的配置工作集中处理:在 app/shopify.server.ts 中配置 OAuth(使用令牌交换而非传统整页重定向)、会话存储与计费;会话通过 Prisma 持久化,默认使用 SQLite;内置 app/uninstalled 与 scope 变更等生命周期 Webhook,以及 App Store 审核要求的三个 GDPR Webhook(customers/data_request、customers/redact、shop/redact)。
项目包含嵌入式应用外壳(AppProvider、NavMenu、错误边界)、一个执行真实 Admin GraphQL 查询的示例页面、计费套餐门控与套餐选择界面,以及公开登录表单和 OAuth 回调路由。非平凡逻辑被抽到 app/lib/ 下作为无框架依赖的函数,并配有 25 个 Vitest 用例,覆盖店铺域名归一化、计费套餐目录和 Webhook 主题到路由名的映射。
需要明确的是,GDPR Webhook 处理器只验证请求并记录载荷,并不真正删除数据,因为模板本身不存储客户 PII;customers/data_request 与 customers/redact 中留有 TODO 标记,只有 shop/redact 会实际删除该店铺的 Session 记录。模板并非开箱即用的 App Store 审核就绪状态,计费配置属于经典按套餐模式而非 Partner Dashboard 中的 Shopify App Pricing,且未提交 CI、Docker 或部署目标。UI 使用 @shopify/polaris(React)而非 Polaris Web Components,npm 已将该包标记为弃用。作者声明其验证方式为 tsc --noEmit、npm run build 和 npm test,未在 CI 中针对线上店铺运行。
适合你的项目吗?
适用场景
- 从零开始搭建一个需要嵌入 Shopify 后台并走 OAuth 的自定义应用
- 为已有应用补齐 App Store 审核所需的三个 GDPR Webhook 路由
- 在 Remix 项目中接入 Shopify Billing API 的按套餐订阅与门控逻辑
- 作为教学或团队内部基线,参考令牌交换、Prisma 会话与 Webhook 路由的组织方式
适合人群
- 使用 Remix 与 Node.js 开发 Shopify 自定义应用的开发者
- 需要快速获得可运行 OAuth、会话与计费骨架的 Shopify Partner
- 希望以 MIT 许可代码为起点并自行决定托管与数据库的团队
上手与定制指南
结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。
- 1
需要 Node.js 18+、npm,以及带开发店铺的 Shopify Partner 账号(均可免费获得)
- 2
依次执行 git clone、npm install、全局安装 @shopify/cli、shopify app config link、npm run setup 与 npm run dev
- 3
仅运行逻辑测试可只执行 npm install 与 npm test,无需 Shopify CLI 或 Partner 账号
- 4
生产环境不应继续使用默认 SQLite,需按 README 修改 prisma/schema.prisma 的 datasource
- 5
上线前应针对自己的开发店铺运行 shopify app dev 验证,模板未在 CI 中对接线上店铺
授权与来源资料
使用条件与限制
免费使用 · 保留许可声明本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。
使用时需要遵守
- 允许免费使用、修改、商用和分发该版本代码。
- 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
- 代码按现状提供;担保与责任限制以原许可证及适用法律为准。
额外费用与待核对事项
- 使用需 Node.js 18+、npm,以及带开发店铺的 Shopify Partner 账号;Partner 账号与开发店铺免费,但必须注册并登录 Partner Dashboard 才能运行完整流程。
- 需将本地目录关联到 Partner Dashboard 中的应用记录,即依赖 Shopify 官方 CLI 与 Partner 账号,属于外部服务依赖。
- 默认 SQLite 仅用于零配置演示,README 明确不建议在生产环境使用,生产需自行更换数据库。
- 模板并非开箱即用的 App Store 审核就绪状态,上线前还需自行补齐隐私政策、权限说明等审核要求。
- GDPR Webhook 处理器只验证请求并记录载荷,不执行数据删除;customers/data_request 与 customers/redact 留有 TODO,需自行接入客户数据查询与删除逻辑。
- 仓库未提供 CI、Docker 或部署目标,托管 Node 进程需自行选择并配置。
- UI 使用已被 npm 标记为弃用的 @shopify/polaris(React)包,而非 Polaris Web Components,长期投入前需注意。
- 作者未在 CI 中针对线上店铺运行验证,上线前需自行用开发店铺测试。
- 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
- 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
查看原文依据
Permission is hereby granted, free of charge
许可证原文
Requires Node.js 18+, npm, and a Partner account with a development store (both free).
README 原文
shopify app config link # links this folder to an app record in your Partner Dashboard
README 原文
No, and you shouldn't — it's here so the template runs with zero external setup.
README 原文
Not App Store review-ready as-is.
README 原文
The GDPR webhook handlers verify the request and log the payload — they don't erase anything
README 原文
No CI, no Docker, no deploy target committed.
README 原文
`@shopify/polaris` (React), not Polaris web components.
README 原文
https://github.com/Ecom-Swift-LLC/shopify-app-starter-remix/blob/main/LICENSEhttps://github.com/Ecom-Swift-LLC/shopify-app-starter-remix/blob/main/README.mdNot deployed or run against a live store by us in CI.
README 原文
DeepSeek 根据仓库许可证和 README 整理 ·2026-10-01。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。
项目核对记录与介绍依据
模板资料
- 来源平台
- GitHub
- 资料与维护参考分
- 资料较完整 · 80 / 100
- 技术栈
- Remix · React
- 网站类型
- 启动器
这个分数如何计算
本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。
这个项目需要核对什么
- 记录的仓库更新时间
- 2026-09-22
- 截图检查日期
- 2026-10-01
已收录演示链接。请用你的内容与屏幕尺寸检查;有演示不代表表单、认证或支付已经可用。
目录记录的主要技术栈是 Remix。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。
查看具体选型方法 →介绍的制作与核对状态
介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。
已完成服务器许可规则与 AI 来源核对;未经过人工编辑审核。
查看当时使用的来源资料
SHA-256: 494b9339fe77961f6a526c56bc3e1fd7ba464e880e4ca1359d683058a1aa5e60
2026-10-01T14:56:43.611Z
来源文件 / 仓库# shopify-app-starter-remix
An embedded Shopify app starter (Remix): OAuth via token exchange, Prisma-backed sessions, all three mandatory GDPR webhooks wired up from day one, and Billing API plan gating — documented with the gotchas the official scaffold leaves for you to hit yourself, and with the parts that can be unit tested actually tested.
We built this because every custom-app engagement starts the same way: `shopify app init`, then an hour of rediscovering which future flags still exist, that billing config now has to be in the line-item shape, and that the GDPR webhooks the App Store will reject you for skipping aren't in the default scaffold at all. This is that hour, done once.
**Free audit for your own store while you're here:** [audit.ecomswiftllc.com](https://audit.ecomswiftllc.com/?utm_source=github&utm_medium=repo&utm_campaign=shopify-app-starter-remix) checks SEO, speed, CRO and AI-visibility in one pass.
## What's inside
| Piece | File(s) |
| --- | --- |
| Shopify app config: OAuth, token exchange, session storage, billing | [`app/shopify.server.ts`](app/shopify.server.ts) |
| Prisma session storage (SQLite by default) | [`prisma/schema.prisma`](prisma/schema.prisma), [`app/db.server.ts`](app/db.server.ts) |
| Embedded app shell: `AppProvider`, `NavMenu`, error boundary | [`app/routes/app.tsx`](app/routes/app.tsx) |
| Example authenticated page (runs a real Admin GraphQL query) | [`app/routes/app._index.tsx`](app/routes/app._index.tsx) |
| Billing plan gate + plan-picker UI | [`app/routes/app.billing.tsx`](app/routes/app.billing.tsx), [`app/lib/plans.ts`](app/lib/plans.ts) |
| Public login form + OAuth callback routes | [`app/routes/auth.login/`](app/routes/auth.login), [`app/routes/auth.$.tsx`](app/routes/auth.$.tsx) |
| App lifecycle webhooks (uninstall, scope change) | [`app/routes/webhooks.app.uninstalled.tsx`](app/routes/webhooks.app.uninstalled.tsx), [`app/routes/webhooks.app.scopes_update.tsx`](app/routes/webhooks.app.scopes_update.tsx) |
| The 3 **mandatory** GDPR webhooks | [`app/routes/webhooks.customers.data_request.tsx`](app/routes/webhooks.customers.data_request.tsx), [`.customers.redact.tsx`](app/routes/webhooks.customers.redact.tsx), [`.shop.redact.tsx`](app/routes/webhooks.shop.redact.tsx) |
| Shop-domain validation for the login form | [`app/lib/shop-domain.ts`](app/lib/shop-domain.ts) |
## Example output
```
$ npm run dev
# Shopify CLI opens a tunnel, prints an install link, and updates
# shopify.app.toml's application_url + redirect_urls for you.
Install the app on your dev store → OAuth via token exchange → lands on
/app, which runs:
query ShopName {
shop { name email }
}
and renders it in a Polaris Card. Click "Billing" in the nav → billing.check()
finds no active subscription → redirects to Shopify's plan-approval page →
approve (free on a dev store) → redirected back to /app/billing showing
"Active plan: Starter".
```
## Features
- **Written and type-checked against what's actually installed, not what the docs say.** `@shopify/[email protected]` made line-item billing and managed-pricing support permanent — the old flat `{ amount, currencyCode, interval }` billing config and the `expiringOfflineAccessTokens` future flag both fail `tsc` now. This repo's `billing` config uses the current `lineItems` shape; run `npx tsc --noEmit` yourself and it's clean.
- **All three mandatory GDPR webhooks, not just `app/uninstalled`.** `customers/data_request`, `customers/redact`, and `shop/redact` are commonly missing from hand-rolled starters and are a real App Store rejection reason — see [what it does NOT do](#what-it-does-not-do) for exactly how much they do and don't implement.
- **The non-trivial logic is unit tested, not just eyeballed.** Shop-domain normalization (handles a bare shop name, a full domain, or a pasted `admin.shopify.com/store/...` URL), the billing plan catalogue, and the webhook-topic-to-route-name mapping live in [`app/lib/`](app/lib) as framework-free functions with 25 Vitest cases.
- **Token exchange, not the classic OAuth redirect.** `unstable_newEmbeddedAuthStrategy: true` is set — the auth strategy Shopify now recommends for embedded apps, instead of the older full-page redirect dance.
- **SQLite by default, one field to change for Postgres/MySQL/MongoDB.** Session storage is `@shopify/shopify-app-session-storage-prisma`; the `Session` model and its adapter don't change, only `prisma/schema.prisma`'s `datasource` block does.
## Installation
Requires Node.js 18+, npm, and a Partner account with a development store (both free).
```bash
git clone https://github.com/Ecom-Swift-LLC/shopify-app-starter-remix.git
cd shopify-app-starter-remix
npm install
npm install -g @shopify/cli # if you don't already have it
shopify app config link # links this folder to an app record in your Partner Dashboard
npm run setup # prisma generate + migrate
npm run dev # opens a tunnel, prints an install link
```
Or run the logic tests on their own, no Shopify CLI or Partner account required:
```bash
npm install
npm test
```
## Usage
- **Add a page:** drop a file in `app/routes/` following Remix's flat-file convention (`app.<name>.tsx` for an embedded page under the nav). Call `authenticate.admin(request)` first in every loader/action — see [`app/routes/app._index.tsx`](app/routes/app._index.tsx).
- **Add a webhook:** add the topic to `shopify.app.toml`'s `[[webhooks.subscriptions]]`, then create `app/routes/webhooks.<topic-with-dots>.tsx` with an action-only route calling `authenticate.webhook(request)`. [`app/lib/webhook-topics.ts`](app/lib/webhook-topics.ts) has the naming convention as a tested function, not just a comment.
- **Change or add a billing plan:** edit [`app/lib/plans.ts`](app/lib/plans.ts)'s `PLANS` object, then mirror the `key` and `lineItems` shape in the `billing` config in `app/shopify.server.ts` — the plan-picker UI in `app.billing.tsx` reads `PLANS` directly, so a new plan shows up with no other changes.
- **Swap the database:** change `prisma/schema.prisma`'s `datasource.provider`/`url` to Postgres/MySQL/MongoDB, run `npx prisma migrate dev`. Nothing else references SQLite directly.
## What it does NOT do
- **The GDPR webhook handlers verify the request and log the payload — they don't erase anything, because this template stores no customer PII of its own.** `customers/data_request` and `customers/redact` have `TODO` markers exactly where you wire in a lookup once your app adds a table keyed to a customer. `shop/redact` *does* do real work — it deletes the shop's `Session` rows — since sessions are the one thing this template actually stores per-shop.
- **Not App Store review-ready as-is.** Wiring the mandatory webhooks is necessary, not sufficient — review also checks your privacy policy, scope justification, and the app's actual behavior on install/uninstall.
- **The Billing API config here is the classic per-plan model, not "Shopify App Pricing."** As of 2026 Shopify is steering new public apps toward pricing that lives in the Partner Dashboard instead of your code — see the note at the top of `app/lib/plans.ts` for which one fits your app.
- **No CI, no Docker, no deploy target committed.** `shopify app deploy` handles the Shopify-side config; hosting the Node process (Fly, Railway, Render, your own box) is a separate decision this repo doesn't make for you.
- **`@shopify/polaris` (React), not Polaris web components.** It's what the current Shopify-maintained Remix template still ships and it works, but npm flags the package itself as deprecated in favor of the web-component version — worth knowing before you invest heavily in Polaris React components.
- **Not deployed or run against a live store by us in CI.** Verified with `npx tsc --noEmit`, `npm run build`, and `npm test` (25 passing) against the exact dependency versions in `package-lock.json` — run `shopify app dev` against your own development store before shipping to production.
## FAQ
**Why does `billing.request` redirect even on a free dev store?**
`isTest: true` (set from `NODE_ENV`) tells Shopify to create the subscription in test mode — the merchant still goes through the approval screen, but no card is ever charged. Development and Partner-org test stores can't be charged real money regardless.
**Why is `app/lib/plans.ts` not `.server.ts` like the other lib files?**
`app.billing.tsx`'s component reads `PLANS` directly to render the plan cards, and Remix's Vite plugin strips `.server.ts` imports from the client bundle — importing one from a component is a build error, not a silent bug. `plans.ts` holds no secret, so it's fine to ship to the browser.
**Do I have to use SQLite in production?**
No, and you shouldn't — it's here so the template runs with zero external setup. Swap `prisma/schema.prisma`'s datasource, per [Usage](#usage) above.
**Where's the `app/routes.ts` route-config file?**
There isn't one — this template deliberately keeps `v3_routeConfig: false` in `vite.config.ts` and uses Remix's classic flat-file route discovery (`app.billing.tsx` → `/app/billing`). Turning that flag on requires migrating to the newer explicit route-config API.
If you'd rather have a custom Shopify app built and maintained than run one yourself, our [free Shopify tools](https://www.ecomswiftllc.com/free-tools) and [store audit](https://audit.ecomswiftllc.com/?utm_source=github&utm_medium=repo&utm_campaign=shopify-app-starter-remix) are a good starting point, or reach out directly — contact details below.
## Related Shopify tools
- [`shopify-webhook-toolkit`](https://github.com/EcomswiftLLC/shopify-webhook-toolkit) — verify, log and replay Shopify webhooks locally while building out the handlers this template stubs.
- [`shopify-checkout-ui-extensions`](https://github.com/Ecom-Swift-LLC/shopify-checkout-ui-extensions) — four tested Checkout UI Extensions to pair with an app built from this starter.
- [`shopify-metafields-manager`](https://github.com/Ecom-Swift-LLC/shopify-metafields-manager) — CLI for the metafield definitions and bulk import an app like this often needs.
- [`shopify-order-export-cli`](https://github.com/Ecom-Swift-LLC/shopify-order-export-cli) — Admin GraphQL order export + revenue reporting, same pagination/retry patterns this template's `admin.graphql` calls would need at scale.
- [`shopify-api-python-client`](https://github.com/EcomswiftLLC/shopify-api-python-client) — the same idea (Admin API client, cost-aware retries) for a Python stack instead of Node.
- [`shopify-audit-mcp`](https://github.com/EcomswiftLLC/shopify-audit-mcp) — the store audit as an MCP tool for Claude, Cursor and other MCP clients.
## Contributing
Issues and PRs welcome — an `app/routes.ts` variant for teams who want the newer route-config API, a Postgres `docker-compose.yml` for local dev, more `app/lib/` coverage, and reports of breakage against newer `@shopify/shopify-app-remix` releases are all useful.
## Roadmap
- An example `app/routes/webhooks.products.update.tsx` showing a filtered webhook subscription (`shopify.app.toml`'s `filter` field).
- A worked usage-based billing example using `createUsageRecord`, alongside the recurring plans already here.
- GitHub Actions workflow running `tsc --noEmit`, `npm test`, and `shopify app config link --client-id` validation on every PR.
## License
MIT © Ecom Swift LLC
## Need help?
This project is maintained by **Ecom Swift LLC**, a Shopify Partner.
- 🛍️ Shopify Partner Directory: https://www.shopify.com/partners/directory/partner/waowy
- ✉️ Email: [email protected]
- 💬 WhatsApp: https://wa.me/16312511767
---
Want a custom Shopify app built on this foundation instead of building it yourself? [Get a free store audit](https://audit.ecomswiftllc.com/?utm_source=github&utm_medium=repo&utm_campaign=shopify-app-starter-remix) (SEO, speed, CRO, AI visibility) or browse our other [free Shopify tools](https://www.ecomswiftllc.com/free-tools). We're **Ecom Swift LLC**, a Shopify Partner Agency — [www.ecomswiftllc.com](https://www.ecomswiftllc.com).
看看同类模板
对比同技术栈与用途的模板,找到更适合的视觉与内容结构。

medusa2-starter
A Turborepo monorepo integrating a Medusa2 backend with a Remix frontend, featuring a Coffee Roast themed dyna…
Remix · 电商

remix-knowledge-base
Knowledge Base starter kit with WYSIWYG, Markdown, GPT, and Multi-language support. Built with Remix, Tailwind…
Remix · 启动器

docs-starter
Remix starter for creating documentation websites with Hygraph
Remix · 文档

directed-stack
Directus + Remix full-stack starter
Remix · 启动器

remix-wasmer-starter
Wasmer Edge JS template for Remix
Remix · 启动器

tailwind-remix-starter
Free and open-source starter kit that helps you get started with Tailwind CSS, Remix and Flowbite React
Remix · 启动器
