PWA - Next.js

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

Nacelle's Next.js accelerator

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

To create a new Nacelle Next starter project:

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

Next.js project manual setup

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

Scaffolding with create-next-app

We can use create-next-app to scaffold a Next.js project:

npx create-next-app@latest

Add Nacelle packages

Nacelle provides packages to easily fetch data from a Nacelle Space and manage carts. To get these packages, run the following command:

npm i @nacelle/storefront-sdk @nacelle/shopify-cart

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. For more information on how Next.js uses environment variables, see the Next.js Environment Variables documentation.

# .env

# Nacelle
NEXT_PUBLIC_NACELLE_STOREFRONT_TOKEN="<YOUR_NACELLE_STOREFRONT_TOKEN>"
NEXT_PUBLIC_NACELLE_STOREFRONT_ENDPOINT="<YOUR_NACELLE_STOREFRONT_ENDPOINT>"

# 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>"

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 exporting a Storefront SDK instance from services/nacelleClient.js:

// services/nacelleClient.js

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

export default new Storefront({
  storefrontEndpoint: process.env.NEXT_PUBLIC_NACELLE_STOREFRONT_ENDPOINT,
  token: process.env.NEXT_PUBLIC_NACELLE_STOREFRONT_TOKEN
});

This will allow the client to be imported wherever it is needed. Next.js provides multiple functions that data can be fetched in. For static generation, getStaticPaths and getStaticProps are explained in the "Static Generation" section of this document. For more details, see Next.js Data Fetching.

Static generation

There are two key functions when setting up static generation for a Next.js project, getStaticPaths and getStaticProps. More information can be found here, Next.js Page Static Generation, but an example can be found below.

getStaticPaths is used when setting up dynamic routing. In the products page below, a list of product handles is queried from the Nacelle Space and returned as a path.

// pages/products/[handle].js

export async function getStaticPaths() {
  const results = await nacelleClient.query({
    query: HANDLES_QUERY
  });
  const handles = results.products
    .filter((product) => product.content?.handle)
    .map((product) => ({ params: { handle: product.content.handle } }));

  return {
    paths: handles,
    fallback: 'blocking'
  };
}

const HANDLES_QUERY = `
  {
    products {
      content {
        handle
      }
    }
  }
`;

getStaticProps is used when data needs to be provided to the page, in this case, an individual product from the Nacelle Space. Below, the handle obtained during getStaticPaths is used as a variable in the query to get product data. If a product is found, it is returned as a prop. If no product is found, the page returns a 404 error.

// pages/products/[handle].js 

export async function getStaticProps({ params }) {
  const { products } = await nacelleClient.query({
    query: PAGE_QUERY,
    variables: { handle: params.handle }
  });

  if (!products.length) {
    return {
      notFound: true
    };
  }

  return {
    props: {
      product: products[0]
    }
  };
}


const PAGE_QUERY = `
  query ProductPage($handle: String!){
    products(filter: { handles: [$handle] }){
      // fields to return
    }
  }
`;

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 Next.js starter or Next.js reference store to see examples of @nacelle/shopify-cart in action with Next.js.