Skip to content

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 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 }
},
})
proxy/reviews.ts -> /proxy/reviews
proxy/api/reviews.ts -> /proxy/api/reviews
proxy/products/[id].ts -> /proxy/products/:id

Files 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 = true

Then send a session token:

const token = await shopify.sessionToken.get()
const response = await fetch(`${apiOrigin}/ext/reviews`, {
headers: {
Authorization: `Bearer ${token}`,
},
})

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.