PWA - Nuxt

Nuxt 2 is a popular open-source Vue metaframework that makes it easy to build performant websites and web applications. To start using Nacelle with Nuxt, follow the quick start guide below to spin up a Nuxt Starter project or create a Nuxt project from scratch.

Nacelle's Nuxt accelerator

While we encourage merchant developers to use create-nuxt-app to scaffold new Nacelle x Nuxt projects, Nacelle's Nuxt starter is a viable option for those who prefer a more featureful starting point than a fresh create-nuxt-app project.

To create a new Nacelle Nuxt starter project:

npx degit https://github.com/getnacelle/nacelle-js/starters/nuxt

Nuxt 2 project manual setup

If you'd prefer not to use Nacelle's Nuxt starter, you can follow the Nuxt 2 manual setup guide below for more control over the initial setup of your project.

Scaffold a new Nuxt project

We can use create-nuxt-app to scaffold a Nuxt 2 project:

npx create-nuxt-app <project-name>

Install the Nacelle Storefront SDK

npm i @nacelle/storefront-sdk

See our Nacelle Storefront SDK docs to learn more about @nacelle/storefront-sdk.

Environment variables

The following environment variables will need to be created to use the Nacelle packages installed in the previous step. See our API settings docs to learn about retrieving variables related to the Nacelle Storefront API.

# .env

# Nacelle
NACELLE_STOREFRONT_ENDPOINT="<YOUR_NACELLE_STOREFRONT_ENDPOINT>"
NACELLE_STOREFRONT_TOKEN="<YOUR_NACELLE_STOREFRONT_TOKEN>"

# Shopify Cart (for details, see: https://www.npmjs.com/package/@nacelle/shopify-cart)
NEXT_PUBLIC_SHOPIFY_SHOP_ID="<YOUR_MYSHOPIFY_DOMAIN>"
NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN="<YOUR_STOREFRONT_CHECKOUT_TOKEN>"

Next, expose the environment variables to the Nuxt app by setting them in the publicRuntimeConfig. For more information, see the Nuxt Runtime Config documentation.

// nuxt.config.js

export default {
  // ...other config,
  publicRuntimeConfig: {
    nacelle: {
      storefrontEndpoint: process.env.NACELLE_STOREFRONT_ENDPOINT,
      token: process.env.NACELLE_STOREFRONT_TOKEN,
      locale: process.env.NACELLE_STOREFRONT_LOCALE
    }
  }
}

Data fetching

The Nacelle Storefront SDK provides multiple methods of getting data from the Nacelle Space. The examples below demonstrate the Nacelle Storefront SDK's .query method, which is used for crafting GraphQL queries sent to the Nacelle Storefront GraphQL API. You can learn more about other methods in our Storefront SDK documentation.

Let's begin by making a Storefront SDK instance available to our app as a Vue plugin:

// plugins/nacelle-sdk.js

import { Storefront } from '@nacelle/storefront-sdk';

export default (context, inject) => {
  const client = new Storefront(context.$config.nacelle);
  inject('nacelle', client);
};

After creating the plugin, we register it in nuxt.config.js:

// nuxt.config.js

export default {
  // ...other config,
  plugins: ['~/plugins/nacelle-sdk.js']
}

Using the asyncData hook

The asyncData lifecycle hook is a perfect place to fetch data for pages. For more information on asyncData, check out Nuxt's asyncData docs.

Below is an example of fetching data for a product page.

// pages/products/_handle.vue

export default {
  async asyncData({ app, params }) {
    const data = await app.$nacelle.query({ 
      query: QUERY, 
      variables: {
        handles: [params.handle]
      } 
    })
    return {
      data
    }
  }
}

const QUERY = `
  query Page($handles: [String!]){
    products(filter: { handles: [$handle] }){
      // fields to return
    }
    content(filter: { handles: [$handle]}) {
      // fields to return
    }
  }
`

Using the fetch hook

The fetch hook is a perfect place to fetch data in components that are not pages. For more information on the fetch hook, see Nuxt's fetch docs.

Below is an example of fetching data for a layout.

// layouts/default/_handle.vue

export default {
  async fetch() {
    this.data = await this.$nacelle.query({ 
      query: QUERY, 
      variables: {
        handles: ['header', 'footer']
      } 
    })
  }
}

const QUERY = `
  query Content($handles: [String!]){
    content(filter: { handles: [$handle] }){
      // fields to return
    }
  }
`

Static Generation

Check out Nuxt’s static generation docs.

Using the generate hook

Check out Nuxt’s generate docs.

To statically generate your site, Nuxt needs to be aware of all dynamic routes. Below is an example of setting up your dynamic product and collection routes for static generation.

// utils/buildRoutes.js

import { Storefront } from '@nacelle/storefront-sdk';

export const buildRoutes = async () => {
  const client = new Storefront({
    storefrontEndpoint: process.env.NACELLE_STOREFRONT_ENDPOINT,
    token: process.env.NACELLE_STOREFRONT_TOKEN,
    locale: process.env.NACELLE_STOREFRONT_LOCALE
  });
  const QUERY = `
    {
      products {
        content {
          handle
        }
      }
      productCollections {
        content {
          handle
        }
      }
    }
  `;

  const response = await client.query({ query: QUERY });
  
  return [
    ...response?.products.map(
      (product) => `/products/${product.content.handle}`
    ),
    ...response?.productCollections.map(
      (productCollection) => `/collections/${productCollection.content.handle}`
    )
  ];
};
// nuxt.config.js

import { buildRoutes } from '~/utils/buildRoutes'

export default {
  // ...other config,
  generate: {
    routes: () => buildRoutes()
  }
}

Cart management

Due to the complexity of Shopify's monolithic system, Nacelle provides the @nacelle/shopify-cart package to manage Shopify carts. Check out our Nuxt starter or Nuxt reference store to see examples of @nacelle/shopify-cart in action with Nuxt.