Add proxy routes
Proxy routes are file-based route handlers in the proxy/ directory. OpenShop mounts them for Shopify app proxy traffic and Customer Account extension traffic.
Create a route
Section titled “Create a route”Create proxy/reviews.ts:
import { app } from '#app'
export default app.defineProxy({ type: 'json', async GET({ shop, customerId, query }) { return { shop, customerId, query } }, async POST({ body }) { return { ok: true, body } },})Understand route paths
Section titled “Understand route paths”proxy/reviews.ts -> /proxy/reviewsproxy/api/reviews.ts -> /proxy/api/reviewsproxy/products/[id].ts -> /proxy/products/:idFiles and directories prefixed with _ are private and do not create routes:
Directoryproxy/
Directoryloyalty/
- _service.ts
- _queries.ts
Directory_shared/
- index.ts
Use private files for helpers that are only useful near the route.
Call the route from a Customer Account extension
Section titled “Call the route from a Customer Account extension”OpenShop also mounts proxy handlers under /ext/* for Customer Account session JWT requests.
Enable network access in the extension TOML:
[extensions.capabilities]network_access = trueThen send a session token:
const token = await shopify.sessionToken.get()
const response = await fetch(`${apiOrigin}/ext/reviews`, { headers: { Authorization: `Bearer ${token}`, },})Verify it worked
Section titled “Verify it worked”For app proxy traffic, Shopify signs the request and OpenShop verifies the HMAC before calling the handler.
For Customer Account traffic, OpenShop verifies the session JWT and sets ctx.shop, ctx.shopifyApp, and ctx.customerId from trusted token claims.
In route code, trust ctx.customerId; do not accept customer IDs from query parameters.