diff --git a/.env.example b/.env.example
index dc6582eb58..75213ad42d 100644
--- a/.env.example
+++ b/.env.example
@@ -1,3 +1,4 @@
+COMPANY_NAME="Vercel Inc."
TWITTER_CREATOR="@vercel"
TWITTER_SITE="https://nextjs.org/commerce"
SITE_NAME="Next.js Commerce"
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
deleted file mode 100644
index a52b961a23..0000000000
--- a/.github/workflows/e2e.yml
+++ /dev/null
@@ -1,49 +0,0 @@
-name: e2e
-on:
- schedule:
- # Runs "at 09:00 and 15:00, Monday through Friday" (see https://crontab.guru)
- - cron: '0 9,15 * * 1-5'
-jobs:
- e2e:
- runs-on: ubuntu-latest
- steps:
- - name: Cancel running workflows
- uses: styfle/cancel-workflow-action@0.11.0
- with:
- access_token: ${{ github.token }}
- - name: Checkout repo
- uses: actions/checkout@v3
- - name: Set node version
- uses: actions/setup-node@v3
- with:
- node-version-file: '.nvmrc'
- - name: Set pnpm version
- uses: pnpm/action-setup@v2
- with:
- run_install: false
- version: 7
- - name: Cache node_modules
- id: node-modules-cache
- uses: actions/cache@v3
- with:
- path: '**/node_modules'
- key: node-modules-cache-${{ hashFiles('**/pnpm-lock.yaml') }}
- - name: Install dependencies
- if: steps.node-modules-cache.outputs.cache-hit != 'true'
- run: pnpm install
- - name: Get playwright version
- run: echo "PLAYWRIGHT_VERSION=$(node -e "console.log(require('./node_modules/@playwright/test/package.json').version)")" >> $GITHUB_ENV
- - name: Cache playwright
- uses: actions/cache@v3
- id: playwright-cache
- with:
- path: '~/.cache/ms-playwright'
- key: playwright-cache-${{ env.PLAYWRIGHT_VERSION }}
- - name: Install playwright browsers
- if: steps.playwright-cache.outputs.cache-hit != 'true'
- run: npx playwright install --with-deps
- - name: Install playwright browser dependencies
- if: steps.playwright-cache.outputs.cache-hit == 'true'
- run: npx playwright install-deps
- - name: Run tests
- run: pnpm test:e2e
diff --git a/README.md b/README.md
index eb611d1ea8..c3fa3f6b52 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fcommerce&project-name=commerce&repo-name=commerce&demo-title=Next.js%20Commerce&demo-url=https%3A%2F%2Fdemo.vercel.store&demo-image=https%3A%2F%2Fbigcommerce-demo-asset-ksvtgfvnd.vercel.app%2Fbigcommerce.png&env=SHOPIFY_REVALIDATION_SECRET,SHOPIFY_STOREFRONT_ACCESS_TOKEN,SHOPIFY_STORE_DOMAIN,SITE_NAME,TWITTER_CREATOR,TWITTER_SITE)
+[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fcommerce&project-name=commerce&repo-name=commerce&demo-title=Next.js%20Commerce&demo-url=https%3A%2F%2Fdemo.vercel.store&demo-image=https%3A%2F%2Fbigcommerce-demo-asset-ksvtgfvnd.vercel.app%2Fbigcommerce.png&env=COMPANY_NAME,SHOPIFY_REVALIDATION_SECRET,SHOPIFY_STORE_DOMAIN,SHOPIFY_STOREFRONT_ACCESS_TOKEN,SITE_NAME,TWITTER_CREATOR,TWITTER_SITE)
# Next.js Commerce
@@ -64,7 +64,7 @@ Next.js Commerce requires a [paid Shopify plan](https://www.shopify.com/pricing)
### Add Shopify domain to an environment variable
-Create a `SHOPIFY_STORE_DOMAIN` environment variable and use your Shopify domain as the the value (ie. `SHOPIFY_STORE_SUBDOMAIN.myshopify.com`).
+Create a `SHOPIFY_STORE_DOMAIN` environment variable and use your Shopify domain as the the value (ie. `[your-shopify-store-subdomain].myshopify.com`).
> Note: Do not include the `https://`.
@@ -74,14 +74,14 @@ Next.js Commerce utilizes [Shopify's Storefront API](https://shopify.dev/docs/ap
In order to use the Shopify's Storefront API, you need to install the [Headless app](https://apps.shopify.com/headless) in your Shopify store.
-Once installed, you'll need to create a `SHOPIFY_STOREFRONT_ACCESS_TOKEN` environment variable and use the public access token as the value
+Once installed, you'll need to create a `SHOPIFY_STOREFRONT_ACCESS_TOKEN` environment variable and use the public access token as the value.
> Note: Shopify does offer a Node.js Storefront API SDK. We use the Storefront API via GraphQL directly instead of the Node.js SDK so we have more control over fetching and caching.
Expand to view detailed walkthrough
-1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/settings/apps`.
+1. Navigate to `https://[your-shopify-store-subdomain].myshopify.com/admin/settings/apps`.
1. Click the green `Shopify App Store` button.

1. Search for `Headless` and click on the `Headless` app.
@@ -94,7 +94,7 @@ Once installed, you'll need to create a `SHOPIFY_STOREFRONT_ACCESS_TOKEN` enviro

1. Copy and paste the public access token and assign it to a `SHOPIFY_STOREFRONT_ACCESS_TOKEN` environment variable.

-1. If you ever need to reference the public access token again, you can navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/headless_storefronts`.
+1. If you ever need to reference the public access token again, you can navigate to `https://[your-shopify-store-subdomain].myshopify.com/admin/headless_storefronts`.
### Install a headless theme
@@ -110,7 +110,7 @@ Follow the installation instructions and configure the theme with your headless
1. Download [Shopify Headless Theme](https://github.com/instantcommerce/shopify-headless-theme).

-1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/themes`.
+1. Navigate to `https://[your-shopify-store-subdomain].myshopify.com/admin/themes`.
1. Click `Add theme`, then `Upload zip file`.

1. Select the downloaded zip file from above, and click the green `Upload file` button.
@@ -142,24 +142,24 @@ You can use Shopify's admin to customize these pages to match your brand and des
#### Checkout, order status, and order history
-1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/settings/checkout`.
+1. Navigate to `https://[your-shopify-store-subdomain].myshopify.com/admin/settings/checkout`.
1. Click the green `Customize` button.

1. Click `Branding` (ie. the paintbrush icon) and customize your brand. Please note, there are three steps / pages to the checkout flow. Use the dropdown to change pages and adjust branding as needed on each page. Click `Save` when you are done.

-1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/settings/branding`.
+1. Navigate to `https://[your-shopify-store-subdomain].myshopify.com/admin/settings/branding`.
1. Customize settings to match your brand.

#### Emails
-1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/settings/email_settings`.
+1. Navigate to `https://[your-shopify-store-subdomain].myshopify.com/admin/settings/email_settings`.
1. Customize settings to match your brand.

#### Favicon
-1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/themes`.
+1. Navigate to `https://[your-shopify-store-subdomain].myshopify.com/admin/themes`.
1. Click the green `Customize` button.

1. Click `Theme settings` (ie. the paintbrush icon), expand the `FAVICON` section, upload favicon, then click the `Save` button.
@@ -190,7 +190,7 @@ Next.js is pre-configured to listen for the following Shopify webhook events and
#### Configure Shopify webhooks
-1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/settings/notifications`.
+1. Navigate to `https://[your-shopify-store-subdomain].myshopify.com/admin/settings/notifications`.
1. Add webhooks for all six event topics listed above. You can add more sets for other preview urls, environments, or local development. Append `?secret=[SECRET]` to each url, where `[SECRET]` is the secret you created above.


@@ -216,7 +216,7 @@ Next.js Commerce is fully powered by Shopify in a truly headless and data driven
#### Products
-`https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/products`
+`https://[your-shopify-store-subdomain].myshopify.com/admin/products`
Only `Active` products are shown. `Draft` products will not be shown until they are marked as `Active`.
@@ -228,7 +228,7 @@ Products that are active and "out of stock" are still shown on the site, but the
#### Collections
-`https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/collections`
+`https://[your-shopify-store-subdomain].myshopify.com/admin/collections`
Create whatever collections you want and configure them however you want. All available collections will show on the search page as filters on the left, with one exception...
@@ -245,7 +245,7 @@ Create the following collections:
#### Pages
-`https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/pages`
+`https://[your-shopify-store-subdomain].myshopify.com/admin/pages`
Next.js Commerce contains a dynamic `[page]` route. It will use the value to look for a corresponding page in Shopify. If a page is found, it will display its rich content using Tailwind's prose. If a page is not found, a 404 page is displayed.
@@ -255,7 +255,7 @@ Next.js Commerce contains a dynamic `[page]` route. It will use the value to loo
#### Navigation menus
-`https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/menus`
+`https://[your-shopify-store-subdomain].myshopify.com/admin/menus`
Next.js Commerce's header and footer navigation is pre-configured to be controlled by Shopify navigation menus. This means you have full control over what links go here. They can be to collections, pages, external links, and more.
diff --git a/app/[page]/layout.tsx b/app/[page]/layout.tsx
index e6d2b7dce7..453253dca7 100644
--- a/app/[page]/layout.tsx
+++ b/app/[page]/layout.tsx
@@ -4,7 +4,7 @@ import { Suspense } from 'react';
export default function Layout({ children }: { children: React.ReactNode }) {
return (
-
+
{children}
diff --git a/app/[page]/page.tsx b/app/[page]/page.tsx
index 7e0defed3e..3dfde9f922 100644
--- a/app/[page]/page.tsx
+++ b/app/[page]/page.tsx
@@ -21,13 +21,6 @@ export async function generateMetadata({
title: page.seo?.title || page.title,
description: page.seo?.description || page.bodySummary,
openGraph: {
- images: [
- {
- url: `/api/og?title=${encodeURIComponent(page.title)}`,
- width: 1200,
- height: 630
- }
- ],
publishedTime: page.createdAt,
modifiedTime: page.updatedAt,
type: 'article'
diff --git a/app/globals.css b/app/globals.css
index c0eca5423c..21bbc4a011 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -7,3 +7,9 @@
clip-path: inset(0.6px);
}
}
+
+a,
+input,
+button {
+ @apply focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 focus-visible:ring-offset-2 focus-visible:ring-offset-neutral-50 dark:focus-visible:ring-neutral-600 dark:focus-visible:ring-offset-neutral-900;
+}
diff --git a/app/layout.tsx b/app/layout.tsx
index dca2c624f0..2674f79fc5 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -33,7 +33,7 @@ const inter = Inter({
export default async function RootLayout({ children }: { children: ReactNode }) {
return (
-
+
{children}
diff --git a/app/page.tsx b/app/page.tsx
index 991a7345ec..aefd193961 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -8,13 +8,6 @@ export const runtime = 'edge';
export const metadata = {
description: 'High-performance ecommerce store built with Next.js, Vercel, and Shopify.',
openGraph: {
- images: [
- {
- url: `/api/og?title=${encodeURIComponent(process.env.SITE_NAME || '')}`,
- width: 1200,
- height: 630
- }
- ],
type: 'website'
}
};
diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx
index 45286cdbe8..63b205c924 100644
--- a/app/product/[handle]/page.tsx
+++ b/app/product/[handle]/page.tsx
@@ -2,16 +2,14 @@ import type { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { Suspense } from 'react';
-import Grid from 'components/grid';
+import { GridTileImage } from 'components/grid/tile';
import Footer from 'components/layout/footer';
-import ProductGridItems from 'components/layout/product-grid-items';
-import { AddToCart } from 'components/cart/add-to-cart';
import { Gallery } from 'components/product/gallery';
-import { VariantSelector } from 'components/product/variant-selector';
-import Prose from 'components/prose';
+import { ProductDescription } from 'components/product/product-description';
import { HIDDEN_PRODUCT_TAG } from 'lib/constants';
import { getProduct, getProductRecommendations } from 'lib/shopify';
import { Image } from 'lib/shopify/types';
+import Link from 'next/link';
export const runtime = 'edge';
@@ -76,43 +74,36 @@ export default async function ProductPage({ params }: { params: { handle: string
};
return (
-