Next.js Commerce

repository·main·Indexed 12 days ago

https://github.com/vercel/commerce

A high-performance, server-rendered ecommerce application template built with the Next.js App Router. It leverages React Server Components, Server Actions, and Suspense to provide a scalable storefront. While optimized for Shopify, it is designed to be extensible for other providers such as BigCommerce, Medusa, and Saleor. Includes built-in utilities for Shopify GraphQL API communication, cart management, and on-demand revalidation via webhooks.

Tokens
5K
Snippets
20
Records
27
Agent score
96%

What's inside Next.js Commerce

  1. Extending Next.js Commerce with alternative commerce providers

    main

    While this repository is optimized for Shopify, it is designed to be extensible. Other commerce providers can use this template by forking the repository and replacing the lib/shopify file with their own implementation. This allows the rest of the template to remain largely unchanged.

    Supported/Compatible Providers include:

    • BigCommerce
    • Ecwid by Lightspeed
    • Geins
    • Medusa
    • Prodigy Commerce
    • Saleor
    • Shopware
    • Swell
    • Umbraco
    • Wix
    • Fourthwall
  2. How to run Next.js Commerce locally

    main

    To run the application on your local machine, you must configure the environment variables defined in .env.example. It is recommended to use Vercel Environment Variables, but a local .env file is sufficient.

    Warning: Do not commit your .env file to version control, as it contains secrets that grant control over your Shopify store.

    Setup Steps

    1. Install the Vercel CLI globally: npm i -g vercel
    2. Link your local instance to your Vercel and GitHub accounts (this creates a .vercel directory): vercel link
    3. Pull your environment variables from Vercel: vercel env pull
    4. Install dependencies and start the development server:
      pnpm install
      pnpm dev

    The application will be available at http://localhost:3000/.

    pnpm install
    pnpm dev
  3. Available Integrations for Next.js Commerce

    main

    Integrations provide upgraded or additional functionality to the core commerce application:

    • Orama: Upgrades search to include typeahead with dynamic re-rendering, vector-based similarity search, and JS-based configuration. Search can run entirely in the browser (for smaller catalogs) or on a CDN (for larger catalogs).
    • React Bricks: Enables visual editing of pages, product details, and footer content using the React Bricks visual headless CMS.
  4. Fetch navigation menus

    main

    The getMenu(handle) function retrieves a Shopify menu by its handle. It reshapes the Shopify menu items into a simplified format suitable for local navigation, replacing Shopify URLs with internal paths (e.g., converting /collections/name to /search/name).

    const menu = await getMenu('main-menu');
    // Returns Menu[]: { title: string; path: string }[]
  5. Manage Shopify cart operations via GraphQL mutations

    main

    This module provides pre-defined GraphQL mutation strings for performing core cart operations using the Shopify Storefront API. These mutations use a shared cartFragment to ensure consistent data shapes for the returned cart object. Use these mutations to create new carts, add items, update existing lines, or remove items.

    // Example: Creating a cart with initial items
    mutation createCart($lineItems: [CartLineInput!]) {
      cartCreate(input: { lines: $lineItems }) {
        cart {
          ...cart
        }
      }
    }
    
    // Example: Adding items to an existing cart
    mutation addToCart($cartId: ID!, $lines: [CartLineInput!]!) {
      cartLinesAdd(cartId: $cartId, lines: $lines) {
        cart {
          ...cart
        }
      }
    }
  6. Fetch products, collections, and pages

    main

    Use these functions to retrieve content from Shopify. Most of these functions use Next.js cache and revalidateTag to optimize performance.

    • getProduct(handle): Fetches a single product by its handle. Automatically filters out products tagged with the hidden product tag.
    • getProducts({ query, reverse, sortKey }): Searches for products. Supports query (string), reverse (boolean), and sortKey (e.g., 'CREATED_AT').
    • getProductRecommendations(productId): Fetches recommended products for a specific product ID.
    • getCollection(handle): Fetches a collection by its handle.
    • getCollections(): Fetches all collections, including a default 'All' collection. Filters out collections starting with hidden-.
    • getCollectionProducts({ collection, reverse, sortKey }): Fetches products within a specific collection.
    • getPage(handle): Fetches a single page by its handle.
    • getPages(): Fetches all pages.
    // Get a product
    const product = await getProduct('my-awesome-product');
    
    // Get products in a collection
    const products = await getCollectionProducts({
      collection: 'summer-collection',
      sortKey: 'CREATED_AT'
    });
  7. Use shopifyFetch to execute GraphQL queries

    main

    The shopifyFetch function is the core utility for communicating with the Shopify Storefront API. It handles the POST request to the GraphQL endpoint, injects the required X-Shopify-Storefront-Access-Token header, and manages error handling for Shopify-specific errors.

    Required Environment Variables:

    • SHOPIFY_STORE_DOMAIN: The domain of your Shopify store (must start with https://).
    • SHOPIFY_STOREFRONT_ACCESS_TOKEN: Your Shopify Storefront API access token.

    Usage: Pass an object containing the query string and optional variables. The function is generic and returns a promise containing the status and the parsed JSON body.

    const res = await shopifyFetch<YourResponseType>({
      query: YOUR_GRAPHQL_QUERY,
      variables: { someId: '123' }
    });
    
    if (res.status === 200) {
      const data = res.body;
      // handle data
    }
  8. Manage the shopping cart with Shopify client functions

    main

    The Shopify client provides high-level functions to manage a user's cart. These functions automatically retrieve the cartId from the request cookies and return a reshaped Cart object that is easier to use in the frontend.

    • createCart(): Initializes a new cart.
    • addToCart(lines): Adds items to the existing cart. lines is an array of { merchandiseId: string; quantity: number }.
    • removeFromCart(lineIds): Removes specific lines from the cart using an array of line IDs.
    • updateCart(lines): Updates quantities or replaces items. lines is an array of { id: string; merchandiseId: string; quantity: number }.
    • getCart(): Retrieves the current cart data based on the cartId in cookies.
    // Add an item to the cart
    const updatedCart = await addToCart([
      { merchandiseId: 'gid://shopify/ProductVariant/123', quantity: 1 }
    ]);
    
    // Update an existing line item
    const updatedCart = await updateCart([
      { id: 'gid://shopify/CartLine/456', merchandiseId: 'gid://shopify/ProductVariant/123', quantity: 2 }
    ]);
  9. Configure Shopify webhook revalidation

    main

    The revalidate(req) function is an exported API route handler designed to be called by Shopify webhooks. It allows Shopify to trigger on-demand revalidation of cached data in Next.js when products or collections change.

    Requirements:

    • An environment variable SHOPIFY_REVALIDATION_SECRET must be set.
    • The request must include a secret query parameter matching that secret.

    Supported Webhook Topics:

    • Collections: collections/create, collections/delete, collections/update (triggers revalidateTag(TAGS.collections)).
    • Products: products/create, products/delete, products/update (triggers revalidateTag(TAGS.products)).

    Other topics will return a 200 OK to Shopify to prevent retries but will not trigger revalidation.

    // This is typically used in an API route like app/api/revalidate/route.ts
    // and called by Shopify via a webhook URL.
    // Example URL: /api/revalidate?secret=YOUR_SHOPIFY_REVALIDATION_SECRET
  10. Reference Shopify GraphQL API endpoint

    main

    The project uses a specific relative path for the Shopify GraphQL API endpoint. Use this constant when configuring API requests or proxying requests to the Shopify backend.

    export const SHOPIFY_GRAPHQL_API_ENDPOINT = "/api/2023-01/graphql.json";
  11. Shopify Cart Item and Product Types

    main

    When working with cart data, use these types to understand the structure of items and their associated product information.

    CartItem

    Represents a single line item in a cart.

    • id: string | undefined
    • quantity: number
    • cost: { totalAmount: Money }
    • merchandise: Contains the id, title, selectedOptions, and the associated product (CartProduct).

    CartProduct

    Simplified product information specifically for cart displays.

    • id: string
    • handle: string
    • title: string
    • featuredImage: Image