Ecommerce with Shopify
The Shopify branch instantly adds a shop to your site by simply supplying Storefront API credentials. At build time, fresh data from the Shopify backend is fetched and used to dynamically render pages with full cart and checkout functionality.
Two ways to add Shopify
Pick the approach that matches the project. Start with the Buy Button for the quickest path, or go headless with the Storefront API for a fully custom storefront.
Option 2: Storefront API
The most common headless Shopify + Astro setup. Astro stays static and excellent at performance, while Shopify still handles payments. Everything below covers this approach.
How the store works
- 1
Connect
Supply your Storefront API credentials
- 2
Fetch
Fresh product data is pulled at build time
- 3
Render
Listing & detail pages generate automatically
- 4
Sell
Cart API builds the cart, Shopify hosts checkout
Where to start
Add your credentials, install dependencies, and run the dev server.
1. Create your .env file
Copy .env.example to .env and add your Shopify store URL along with your public and private access tokens.
# .env , copy from .env.example, then fill in your values PUBLIC_SHOPIFY_STORE_URL=your-store.myshopify.com PUBLIC_SHOPIFY_STOREFRONT_TOKEN=your_public_access_token PRIVATE_SHOPIFY_STOREFRONT_TOKEN=your_private_access_token
2. Review the config
The credentials are consumed inside src/utils/config.ts. You can bump the Storefront API version there whenever you need newer fields.
// src/utils/config.ts // Credentials are read here from your .env file. // Bump the Storefront API version whenever you need newer fields. export const SHOPIFY_API_VERSION = "2024-10";
3. Install & run
Install dependencies with your package manager of choice, then start the dev server.
# Install dependencies npm install # or: yarn / pnpm install # Start the dev server npm run dev # or: yarn dev / pnpm dev
Shopify Configuration Guide
Connect a Shopify store and grant the Storefront API the right scopes.
- 1
Create or sign in to a Shopify account
Use an existing store or create a new one at accounts.shopify.com.
- 2
Add the Headless sales channel
From your store admin, add the Shopify Headless channel, then click Add Storefront.
- 3
Copy your access tokens
Copy the public and private access tokens into your
.envfile. - 4
Set your Storefront API access scopes
Check Storefront API access scopes.
unauthenticated_read_product_listingsandunauthenticated_read_product_inventoryare enough to get started, add more scopes if you need additional permissions.
Minimum scopes to get started
unauthenticated_read_product_listings and unauthenticated_read_product_inventory cover product browsing and stock. Add more scopes only as your storefront needs them.What's Included
A lightning-fast frontend that rivals Shopify's own themes.
This branch ships a generic product listing and product detail page setup that adapts based on the collections and products defined in your Shopify backend. The Storefront API query is pre-configured to fetch the extra product information you need, transformed into an easy-to-follow format before the site renders.
Generic, adaptive pages
A product listing and product detail setup that adapts to whatever collections and products are defined in the Shopify backend.
Preset Storefront query
A ready-made GraphQL Storefront API query fetches the most commonly required product fields out of the box.
Build-time transform
Data is reshaped at build time into an easy-to-follow format to streamline injection, while keeping the raw GraphQL data available.
The preset Storefront query
A single GraphQL query pulls the most commonly required product fields. Extend it with any fields your store needs from the Storefront API reference.
query Products {
products(first: 50) {
edges {
node {
id
title
handle
description
priceRange {
minVariantPrice {
amount
currencyCode
}
}
featuredImage {
url
altText
}
variants(first: 1) {
edges {
node { id }
}
}
}
}
}
}Cart & Checkout
Wiring up cart and checkout takes two lines.
Setting up button functionality is as simple as defining the variant ID on the page and specifying where you want the button to render. On click, the component creates a cart with the Storefront Cart API and redirects the customer to the checkoutUrl it returns, landing them on Shopify's hosted checkout.
---
// src/pages/products/[handle].astro
import BuyButton from "../../components/BuyButton.astro";
// Pass the variant's global ID; drop the button wherever you like.
const variantId = "gid://shopify/ProductVariant/1234567890";
---
<BuyButton variantId={variantId} quantity={1} />Under the hood, the component runs a cartCreate mutation and follows the returned URL:
// On click, create a cart for the chosen variant…
const res = await storefront(`
mutation CartCreate($lines: [CartLineInput!]!) {
cartCreate(input: { lines: $lines }) {
cart { checkoutUrl }
userErrors { field message }
}
}
`, { lines: [{ merchandiseId: variantId, quantity }] });
// …then hand the buyer off to Shopify's hosted checkout.
window.location.href = res.data.cartCreate.cart.checkoutUrl;Finding the variant ID
gid://shopify/ProductVariant/…) from the variants field in the Storefront API response. The Cart API takes a merchandiseId (a variant), not a product ID.Pros
- Fully custom storefront
- Excellent performance
- Astro stays static
- Shopify handles payments
Cons
- More development work
Project Structure
Where everything lives inside the template.
/ ├── public/ ├── src/ │ ├── components/ │ │ └── Header.astro │ ├── layouts/ │ │ └── BaseLayout.astro │ ├── pages/ │ │ └── index.astro │ ├── stores/ │ │ └── cart.ts │ ├── styles/ │ │ └── global.css │ └── utils/ │ └── shopify.ts └── package.json
- Astro looks for
.astroor.mdfiles insrc/pages/. Each file is exposed as a route based on its name. src/components/is where Astro/React/Vue/Svelte/Preact components live, there's nothing special about it, it's just convention.- Static assets like images go in
public/, andsrc/utils/shopify.tsholds the Storefront API helpers and cart logic.
