Middleware
shopify-auth
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.
How It Works
| Environment | Check | Redirect |
|---|---|---|
| Server (SSR) | Looks for the shop query parameter that Shopify always provides when loading an embedded app | Stores the current URL in a shopify-redirect-to cookie and redirects to the auth page if missing |
| Client | Checks window.shopify.config.shop from App Bridge | Stores the current URL in a shopify-redirect-to cookie and redirects to the auth page if unavailable |
If the check fails on either side, the middleware saves the attempted URL in a shopify-redirect-to cookie (so the user can be sent back after login) and navigates to the auth page (default /auth). The path is configurable via authPagePath in the public runtime config.
Usage
Add definePageMeta({ middleware: 'shopify-auth' }) to any page that should require authentication:
<script setup>
definePageMeta({
middleware: 'shopify-auth'
})
</script>
<template>
<ShPage title="Dashboard">
<!-- Only renders when authenticated -->
</ShPage>
</template>
You can also apply it to a layout if all pages under that layout need protection:
<!-- layouts/default.vue -->
<script setup>
definePageMeta({
middleware: 'shopify-auth'
})
</script>
<template>
<ShApp>
<slot />
</ShApp>
</template>
Source
defineNuxtRouteMiddleware((to) => {
const config = useRuntimeConfig().public.shopify
const authPage = config.authPagePath || '/auth'
const redirectTo = useCookie('shopify-redirect-to')
if (import.meta.server) {
const shop = to.query.shop as string | undefined
if (!shop) {
redirectTo.value = to.fullPath
return navigateTo(authPage)
}
return
}
const shop = window.shopify?.config?.shop
if (!shop) {
redirectTo.value = to.fullPath
return navigateTo(authPage)
}
})
shopify-guest
A named Nuxt route middleware for pages that should only be accessible to unauthenticated users — most notably the login page. If the user is already authenticated, it redirects them away. It is auto-registered by the module and applied to the built-in auth-login.vue page by default.
How It Works
| Environment | Check | Redirect |
|---|---|---|
| Server (SSR) | No check — allows the page to render | — |
| Client | Checks window.shopify.config.shop from App Bridge | If a shop is configured (authenticated), redirects to the URL stored in the shopify-redirect-to cookie, or / if no cookie is set |
This works hand-in-hand with shopify-auth: when an unauthenticated user tries to visit a protected page, shopify-auth stores the target URL in a cookie and redirects to /auth. Once the merchant completes login and App Bridge initialises, shopify-guest picks up the stored URL and sends them back to where they originally wanted to go.
Usage
Apply it to your login or guest-only pages:
<script setup>
definePageMeta({
layout: false,
middleware: 'shopify-guest'
})
</script>
The built-in auth-login.vue page already includes this middleware.
Source
defineNuxtRouteMiddleware(() => {
const redirectTo = useCookie('shopify-redirect-to')
if (import.meta.server) {
return
}
const shop = window.shopify?.config?.shop
if (shop) {
const target = redirectTo.value || '/'
redirectTo.value = null
return navigateTo(target)
}
})
Default Auth Login Page
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.
What It Does
- Presents a centered card with the Shopify logo, a shop domain input field, and a Log in button
- Accepts a bare store name (e.g.,
my-shop) or a full domain (my-shop.myshopify.com) - On submit, redirects the merchant to the OAuth flow at
{authPathPrefix}?shop={domain}
Appearance
The page renders with layout: false, applies the shopify-guest middleware (so authenticated users are redirected away), and uses self-contained scoped styles that match the Shopify admin aesthetic — no Polaris dependency required.
Controlling the Auth Page
The authPage module option controls this page:
| Value | Behavior |
|---|---|
| (not set) | Registers the default auth-login.vue at /auth |
false | Disables the built-in page entirely — you must handle the route yourself |
'/path/to/MyLogin.vue' | Registers your custom component at /auth instead |
// nuxt.config.ts
export default defineNuxtConfig({
shopify: {
// Use defaults (built-in login page at /auth)
// authPage: undefined
// Disable the built-in page
// authPage: false
// Use a custom component
// authPage: '~/components/MyShopifyLogin.vue'
}
})
Overriding the Page
To fully customize the login experience while keeping the same route, create your own component and point authPage to it. Your component should:
- Collect the shop domain from the merchant
- Redirect to
{authPathPrefix}?shop={domain}withexternal: true
<!-- components/MyShopifyLogin.vue -->
<script setup>
definePageMeta({ layout: false, middleware: 'shopify-guest' })
const shop = ref('')
const config = useRuntimeConfig()
function login() {
const domain = shop.value.includes('.myshopify.com')
? shop.value
: `${shop.value}.myshopify.com`
navigateTo(
`${config.public.shopify.authPathPrefix}?shop=${encodeURIComponent(domain)}`,
{ external: true }
)
}
</script>
<template>
<form @submit.prevent="login">
<input v-model="shop" placeholder="your-shop" />
<button type="submit">Install</button>
</form>
</template>