Nuxt Shopify
Magic Shopify GraphQL API-Connector for Nuxt 3 & 4.
⚡️ Features
- 🔗 Fully typed fetch client from GraphQL schemas
- 🔥 Hot-reloads types automatically when your GraphQL changes
- 🔐 Secure access token handling
- 🛒 Storefront and Admin API support
- 🌐 Server & client side support
- 🛠️ Automatic mock.shop integration
- 🚩 Error handling optimized for Nuxt
- 🧩 GraphQL fragments support
- ⚙️ Customizable GraphQL code generation
- 📦 Auto-imports for GraphQL queries and generated types
- 🧪 Tested with Nuxt 3 & 4
- 🔄 Hooks for customizing the module behavior
- 🏖️ Sandbox integrated with GraphiQL Explorer
Roadmap
Upcoming features and developments for the 1.0.0 release:
- 👤 Customer Account API support
- 🔍 Shopify Analytics support
- 🛍️ Store template with Nuxt UI & Nuxt Content
📦 Setup
Run the following command to install the module in your project:
npx nuxt@latest module add nuxt-shopify
Or use the manual installation
- Install the module via npm:
npm install @konkonam/nuxt-shopify
- Add the module to your
nuxt.config.ts
:export default defineNuxtConfig({ modules: [ '@konkonam/nuxt-shopify', ], })
Add your Shopify configuration to the nuxt.config.ts
:
export default defineNuxtConfig({
shopify: {
name: 'quickstart-abcd1234',
clients: {
storefront: {
apiVersion: '2025-07',
publicAccessToken: 'YOUR_ACCESS_TOKEN',
},
admin: {
apiVersion: '2025-07',
accessToken: 'YOUR_ACCESS_TOKEN',
},
},
},
})
🛠️ Usage
Access Storefront API on the client side
There are multiple ways of communicating with the Shopify APIs.
The easiest way is with the useStorefront
composable, directly inside of your vue component or page.
To access the
useStorefront
composable on the client side, make sure you have added a public access token. You can add it in the module config:clients > storefront > publicAccessToken
<!-- ~/pages/your-page.vue -->
<script setup lang="ts">
const storefront = useStorefront()
const { data } = await storefront.request(`#graphql
query FetchProducts($first: Int) {
products(first: $first) {
nodes {
id
title
description
}
}
}
`, {
variables: {
first: 3,
},
})
</script>
<template>
<pre>{{ data?.products }}</pre>
</template>
This will fetch the first three products from your Shopify store and display them in a <pre>
tag.
The data
variable will be typed as FetchProductsQuery
, which is auto-generated by the module to enable autocompletion and full type checking.
You can use this generated FetchProductsQuery
type anywhere in your code to ensure type safety when working with the query response within components.
Access APIs via Nitro endpoints
The module exposes utilities to access each API via Nitro endpoints.
Storefront API example
You can use the useStorefront
utility to access the storefront API:
// ~/server/api/products.ts
export default defineEventHandler(async () => {
const storefront = useStorefront()
return await storefront.request(`#graphql
query FetchProducts($first: Int) {
products(first: $first) {
nodes {
id
title
description
}
}
}
`, {
variables: {
first: 3,
},
})
})
Notice how we can use the graphql
directive inside the event handler, this is possible because in
the standard module configuration all .ts
and .gql
files are automatically processed for the
storefront API, as long as the don't end with .admin.ts
or .admin.gql
.
Read more about the codegen configuration.
Now we can call the API at /api/products
to obtain the first three products:
<!-- ~/pages/your-page.vue -->
<script setup lang="ts">
const { data } = await useFetch('/api/products')
</script>
<template>
<pre>{{ data }}</pre>
</template>
The data
variable will be typed as Ref<ClientResponse<FetchProductsQuery>>
, which enables autocompletion and full
type checking.
Admin API example
Files ending with .admin.ts
or .admin.gql
will automatically be processed for the admin API.
We can use the useAdmin
utility to access the admin API in a nitro event handler:
// ~/server/api/your-admin-api-handler.ts
export default defineEventHandler(async () => {
const admin = useAdmin()
return await admin.request(...)
})
For a full example, see Admin API examples.
Mock the Storefront API
To mock the Storefront API, you can use the mock
option in the module config:
export default defineNuxtConfig({
shopify: {
name: 'my-mocked-shopify-store',
clients: {
storefront: {
mock: true,
apiVersion: '2025-07',
},
},
},
})
All requests to the Storefront API will now return data from mock.shop instead of hitting the actual Shopify API.
Type generation
Once installed, the module automatically generates your GraphQL types and saves them in:
- .nuxt/types — Type definitions
- .nuxt/schema — GraphQL schema files
To enable IDE support, you can add a GraphQL configuration file:
# ~/graphql.config.yml
schema:
- ./.nuxt/schema/storefront.schema.json
- ./.nuxt/schema/admin.schema.json
Handling GraphQL fragments
You can define reusable fragments in your GraphQL queries to avoid duplication and make your queries more maintainable. The module supports fragment usage out of the box.
Here's an example of how to define and use a fragment:
#graphql
fragment ProductFields on Product {
id
title
description
}
query FetchProducts($first: Int) {
products(first: $first) {
nodes {
...ProductFields
}
}
}
You can place this query in a .gql
, .ts
or .vue
file and use it in your requests. The module will be able to import the fragment and allow you to use it directly within your GraphQL operation.
Files placed in the ~/graphql
directory will be automatically imported by the module, so it is recommended to organize your fragments there.
Handling errors
By default, the module will throw an error if the storefront or admin client encounters an error instead of returning the errors object in the response. This is done so that Nuxt can take over the error handling.
You can customize this behavior by setting the errors.throw
option in the module config.
export default defineNuxtConfig({
shopify: {
errors: {
throw: false,
},
},
})
This will prevent the module from throwing an error and instead return the error response.
The module also provides hooks to handle errors.
// ~/server/plugins/your-plugin.ts
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('storefront:client:errors', ({ errors }) => {
// Do something with the errors
console.log('Storefront client errors:', errors)
})
})
Read more about all available hooks in our hooks documentation.
🤝 Contributing
- Clone this repository
- Create a
.env
file (see.env.example
) - Install dependencies using:
bun install
- Run
bun run prepare:dev
to generate type stubs. - Start the default playground with:
bun run dev
📜 License
Published under the MIT License.