Nitrogen is a Nuxt template inspired by Shopify's Hydrogen framework for headless commerce. This template is designed to empower Nuxt developers to build fast, scalable, and customizable storefronts that incorporate key features from Hydrogen's starter theme.
Important
This template now features a minimal Sanity studio template, which synchronizes content between a Sanity dataset and your Shopify storefront. This allows teams to further enhance product and collection pages with custom content or curated links โ anything, really.
- ๐ช Strongly typed
- ๐ Cart functionality
- ๐ User authentication, with password reset
- ๐ค Full customer account functionality
- ๐๏ธ Collection pages, with pagination
- ๐น๏ธ Collection filter and sort functionality
- ๐ Product pages, with metafields
- ๐ Search functionality
- ๐ Shop localization
- ๐ก Sitemap, with robots
- ๐ซ Klaviyo integration
- ๐ Embla Carousel
- ๐จ Tailwind v4
- ๐ฎ Codegen
Tip
Read through the docs to learn how to configure your Shopify store to work with Nitrogen!
To begin using Nitrogen, you'll need to add the following environment variables:
# Shopify
NUXT_SHOPIFY_DOMAIN=your-shop-name.myshopify.com
NUXT_SHOPIFY_ADMIN_ACCESS_TOKEN=your_admin_access_token
NUXT_SHOPIFY_STOREFRONT_ACCESS_TOKEN=your_storefront_access_token
NUXT_SHOPIFY_API_VERSION=2025-01
# Klaviyo (optional)
NUXT_KLAVIYO_PUBLIC_API_KEY=your_public_api_key
NUXT_KLAVIYO_PRIVATE_API_KEY=your_private_api_key
NUXT_KLAVIYO_API_VERSION=2025-01-15
# Sanity (optional)
NUXT_SANITY_PROJECT_ID=your_project_id
NUXT_SANITY_DATASET=production
NUXT_SANITY_API_VERSION=2025-02-02
NUXT_SANITY_STUDIO_URL=http://your-site-domain.com
NUXT_SANITY_API_READ_TOKEN=your_api_read_token
Warning
It is strongly recommended that you use the 2025-01
Storefront API version or higher. If not, you will not have access to new API features found within this template (this will cause breaking changes).
- Install dependencies using
pnpm install
- Generate your project types using
pnpm codegen
- Start the development server using
pnpm dev
Nitrogen features two custom modules for Shopify and Klaviyo, located in the /modules
folder. The Shopify module, in particular, lets you connect to both the Storefront and Admin APIs at the same time, which is really cool for building more complex storefronts that may use Shopify to act a database in some way (think wishlist functionality or unique customer account features).
Tip
Read the official Nuxt Author Module Guide to learn how to create and manage your own modules.
A minimal GraphQL client is provided to seamlessly integrates with both the Shopify Storefront and Admin APIs (at the same time). It uses two server-side proxies to handle API authentication and requests, while offering a typed interface for executing GraphQL operations.
This project includes pre-built GraphQL operations for common Storefront and Admin API queries and mutations. Feel free to add or remove operations that fit your project needs.
To get GraphQL operations, use the useShopify
composable:
const shopify = useShopify()
Operations can be referenced using this composable with dot notation:
// Shopify
const shopify = useShopify()
// With dot notation
await shopify.cart.addLines(cart.id, [ ... ])
await shopify.product.get({ handle: 'example-product' })
Perfect for reactive data fetching in pages or components:
// Shopify
const shopify = useShopify()
// Fetch Shopify data
const productVars = computed<ProductQueryVariables>(() => ({
handle: handle.value,
country: shopStore.buyerCountryCode,
language: shopStore.buyerLanguageCode,
}))
const { data: productData } = await useAsyncData(
`product-${handle.value}`,
() => shopify.product.get(productVars.value),
{ watch: [productVars] },
)
// Response data
const product = computed(() => productData.value)
Ideal for working with actions in your Pinia stores:
// Shopify
const shopify = useShopify()
// Cart store actions
actions: {
async createCart(input?: CartInput, optionalParams?: CartOptionalInput) {
try {
const response = await shopify.cart.create({
input: input,
...optionalParams,
})
if (response?.userErrors?.length) {
throw new Error(response?.userErrors[0]?.message)
}
this.cart = response?.cart
} catch (error: any) {
console.error('Cannot create cart:', error.message)
throw error
}
},
// More cart actions...
}
Contributions are always welcome! If youโd like to help improve this project, hereโs how you can get involved:
- Post an issue: Use the Issues tab to report bugs or request new features.
- Start a discussion: Share ideas or ask for help in the Discussions tab.
- Submit a pull request: If youโd like to contribute, fork the repository, make your changes, and submit a pull request for review.
I actively monitor this repository and will do my best to respond quickly. Whether itโs fixing a small typo or adding a new feature, every contribution helps!