Skip to content

Commit 39863fc

Browse files
committed
feat: add middleware and types documentation for Shopify authentication
1 parent 72795e5 commit 39863fc

2 files changed

Lines changed: 151 additions & 0 deletions

File tree

docs/content/3.api/4.middleware.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
---
2+
title: Middleware
3+
description: Client-side route middleware for Shopify authentication and the built-in login page.
4+
navigation:
5+
icon: i-lucide-shield-check
6+
seo:
7+
title: Middleware — shopify-app-nuxt API Reference
8+
description: Reference for the shopify-auth route middleware and the default auth-login page component.
9+
---
10+
11+
## `shopify-auth`
12+
13+
A **named** Nuxt route middleware that guards pages requiring an authenticated Shopify session. It is auto-registered by the module but **not global** — you opt-in per page.
14+
15+
### How It Works
16+
17+
| Environment | Check | Redirect |
18+
| --- | --- | --- |
19+
| **Server (SSR)** | Looks for the `shop` query parameter that Shopify always provides when loading an embedded app | Redirects to the auth page if missing |
20+
| **Client** | Checks `window.shopify.config.shop` from App Bridge | Redirects to the auth page if unavailable |
21+
22+
If the check fails on either side, the middleware navigates to the auth page (default `/auth`). The path is configurable via `authPagePath` in the public runtime config.
23+
24+
### Usage
25+
26+
Add `definePageMeta({ middleware: 'shopify-auth' })` to any page that should require authentication:
27+
28+
```vue
29+
<script setup>
30+
definePageMeta({
31+
middleware: 'shopify-auth'
32+
})
33+
</script>
34+
35+
<template>
36+
<ShPage title="Dashboard">
37+
<!-- Only renders when authenticated -->
38+
</ShPage>
39+
</template>
40+
```
41+
42+
You can also apply it to a layout if all pages under that layout need protection:
43+
44+
```vue
45+
<!-- layouts/default.vue -->
46+
<script setup>
47+
definePageMeta({
48+
middleware: 'shopify-auth'
49+
})
50+
</script>
51+
52+
<template>
53+
<ShopifyAppProvider>
54+
<slot />
55+
</ShopifyAppProvider>
56+
</template>
57+
```
58+
59+
### Source
60+
61+
```ts
62+
defineNuxtRouteMiddleware((to) => {
63+
const config = useRuntimeConfig().public.shopify
64+
const authPage = config.authPagePath || '/auth'
65+
66+
if (import.meta.server) {
67+
const shop = to.query.shop as string | undefined
68+
if (!shop) return navigateTo(authPage)
69+
return
70+
}
71+
72+
const shop = window.shopify?.config?.shop
73+
if (!shop) return navigateTo(authPage)
74+
})
75+
```
76+
77+
---
78+
79+
## Default Auth Login Page
80+
81+
The module ships a built-in `/auth` page (`auth-login.vue`) that provides a styled login form for merchants. It is automatically registered unless explicitly disabled.
82+
83+
### What It Does
84+
85+
1. Presents a centered card with the Shopify logo, a shop domain input field, and a **Log in** button
86+
2. Accepts a bare store name (e.g., `my-shop`) or a full domain (`my-shop.myshopify.com`)
87+
3. On submit, redirects the merchant to the OAuth flow at `{authPathPrefix}?shop={domain}`
88+
89+
### Appearance
90+
91+
The page renders with `layout: false` (no app shell) and uses self-contained scoped styles that match the Shopify admin aesthetic — no Polaris dependency required.
92+
93+
### Controlling the Auth Page
94+
95+
The `authPage` module option controls this page:
96+
97+
| Value | Behavior |
98+
| --- | --- |
99+
| *(not set)* | Registers the default `auth-login.vue` at `/auth` |
100+
| `false` | Disables the built-in page entirely — you must handle the route yourself |
101+
| `'/path/to/MyLogin.vue'` | Registers your custom component at `/auth` instead |
102+
103+
```ts
104+
// nuxt.config.ts
105+
export default defineNuxtConfig({
106+
shopify: {
107+
// Use defaults (built-in login page at /auth)
108+
// authPage: undefined
109+
110+
// Disable the built-in page
111+
// authPage: false
112+
113+
// Use a custom component
114+
// authPage: '~/components/MyShopifyLogin.vue'
115+
}
116+
})
117+
```
118+
119+
### Overriding the Page
120+
121+
To fully customize the login experience while keeping the same route, create your own component and point `authPage` to it. Your component should:
122+
123+
1. Collect the shop domain from the merchant
124+
2. Redirect to `{authPathPrefix}?shop={domain}` with `external: true`
125+
126+
```vue
127+
<!-- components/MyShopifyLogin.vue -->
128+
<script setup>
129+
definePageMeta({ layout: false })
130+
131+
const shop = ref('')
132+
const config = useRuntimeConfig()
133+
134+
function login() {
135+
const domain = shop.value.includes('.myshopify.com')
136+
? shop.value
137+
: `${shop.value}.myshopify.com`
138+
navigateTo(
139+
`${config.public.shopify.authPathPrefix}?shop=${encodeURIComponent(domain)}`,
140+
{ external: true }
141+
)
142+
}
143+
</script>
144+
145+
<template>
146+
<form @submit.prevent="login">
147+
<input v-model="shop" placeholder="your-shop" />
148+
<button type="submit">Install</button>
149+
</form>
150+
</template>
151+
```
File renamed without changes.

0 commit comments

Comments
 (0)