Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
25ddc5e
Update dependencies. (#1314)
leerob Mar 26, 2024
610b0e8
Remove stray revalidate
leerob Mar 31, 2024
887d437
Prepare for using PPR (#1236)
leerob Apr 18, 2024
a5de917
fix: disabled button classes when selectedVariantId is defined are no…
elberthcorniell May 4, 2024
42d5d8e
Adds Ecwid by Lightspeed to providers section (#1304)
meteor-ec May 7, 2024
7fd9ad8
Update README.md (#1339)
JustinApt May 26, 2024
7c1b34a
Remove any type and make removeEdgesAndNodes generic (#1353)
harrybuisman Jul 14, 2024
ec21369
Update dependencies. (#1361)
leerob Jul 24, 2024
d7a4f3d
feat(design): Show carousel above the fold on desktop (#1363)
vvo Jul 25, 2024
0ebf071
Optimistic cart (#1364)
leerob Jul 25, 2024
cea56f6
Fix bugs with optimistic.
leerob Jul 25, 2024
dd7449f
Make deleting optimistic too.
leerob Jul 25, 2024
9a4c995
Make image, variant, and cart updates faster with `useOptimistic` (#1…
leerob Jul 29, 2024
37cb5e3
Small cleanup.
leerob Jul 29, 2024
94b85fc
Update README
leerob Jul 29, 2024
84224f8
Fix bug with disabled state
leerob Jul 29, 2024
556aa77
README: added React Bricks integration (#1367)
matteofrana Aug 7, 2024
694c5c1
Move to `next/form` (#1369)
leerob Aug 13, 2024
83856a4
Squashed commit of the following:
ah100101 Sep 5, 2024
40e8b79
fixed sitemap
ah100101 Sep 5, 2024
12ca470
added shadcn/ui
ah100101 Sep 5, 2024
7c4b3b0
connected cart on checkout to sfcc
ah100101 Sep 5, 2024
8311ef3
Update image URL in reshapeImages function and add new hostname for sfcc
ah100101 Sep 5, 2024
5b9bea7
typo on checkout
ah100101 Sep 5, 2024
64ca2ac
Update to 15 RC 2
leerob Oct 16, 2024
815bea2
chore: update readme (#1381)
bnzone Oct 16, 2024
cb99695
Correct default cart tax currency (#1260)
matthew-petrie Oct 16, 2024
b7e9e1c
Refactor <Prose> component (#1352)
chogyejin Oct 16, 2024
ce004c0
Update tailwind.config.ts (#1388)
omkarkulkarni2704 Oct 18, 2024
8d4cc9a
fixing response status code for no secret or wrong secret (#1397)
newlomar Oct 27, 2024
cf413a5
Update gallery.tsx (#1403)
dharmveer97 Nov 21, 2024
3a26bae
Add Fourthwall as a commerce provider (#1394)
jurrchen Nov 21, 2024
386392b
feat: added geins as a commerce provider (#1414)
arvidsson-geins Nov 28, 2024
88762ba
Update deps
leerob Dec 6, 2024
6759421
Adds Prodigy Commerce as a commerce provider. (#1415)
polykoi Jan 21, 2025
7f8f9ff
use cache
leerob Feb 9, 2025
6946bf7
Fix production base url (#1429)
johnstringerm Feb 10, 2025
63725d8
Update deps
leerob Feb 21, 2025
9f4fdbb
Merge branch 'main' of github.com:vercel/commerce
leerob Feb 21, 2025
28f9a64
Update Wix fork repository (#1439)
netanelgilad Feb 24, 2025
7297c2e
merge in latest next commerce changes
ah100101 Mar 6, 2025
092b26e
merge 15-2 upgrade into commerce sfcc
ah100101 Mar 6, 2025
a328360
merge next-15-2 branch into main
ah100101 Mar 6, 2025
18e6c36
Merge remote-tracking branch 'ah100101-commerce/checkout' into checkout
ah100101 Mar 6, 2025
52842e1
merge checkout branch into main
ah100101 Mar 6, 2025
cc60e93
refactor: improve environment variable validation and error handling
darekrossman Mar 24, 2025
a1db83d
Undo accidental main commit
darekrossman Mar 24, 2025
93ed08b
Refactor SFCC SDK implementation and configuration (#2)
darekrossman Mar 26, 2025
89a3ec3
Implement SFCC Checkout Flow (#3)
darekrossman Mar 26, 2025
56a74a1
Checkout summary enhancements (#3) (#4)
darekrossman Apr 7, 2025
a2a4421
Price range and other bugs (#7)
darekrossman Apr 11, 2025
f5ec866
Refactor SFCC Utilities (#9)
ah100101 Apr 23, 2025
f7270c9
Refactored constants to sfcc/constants (#10)
ah100101 Apr 23, 2025
dacc982
Style: Apply code formatting across codebase (#11)
ah100101 Apr 25, 2025
b754a1a
Implement 'use cache' for improved data caching (#12)
ah100101 Apr 28, 2025
786c3e3
Update environment variables and README for clarity (#13)
ah100101 Apr 29, 2025
d0d3a11
README Update for Salesforce Commerce Cloud (#14)
ah100101 May 12, 2025
28ad68c
docs: Add SFCC integration and setup to README (#15)
ah100101 Jun 2, 2025
d059200
URGENT: Upgrade required for React CVE-2025-55182 (#17)
ctate Dec 11, 2025
21017b3
refactor: Update TypeScript configuration and improve revalidation lo…
ah100101 Dec 11, 2025
a421f54
fix: Fix React Server Components CVE vulnerabilities
malewis5 Dec 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
COMPANY_NAME="Vercel Inc."
TWITTER_CREATOR="@vercel"
TWITTER_SITE="https://nextjs.org/commerce"
SITE_NAME="Next.js Commerce"
SHOPIFY_REVALIDATION_SECRET=""
SHOPIFY_STOREFRONT_ACCESS_TOKEN=""
SHOPIFY_STORE_DOMAIN="[your-shopify-store-subdomain].myshopify.com"
NEXT_PUBLIC_VERCEL_URL="http://localhost:3000"
SFCC_CLIENT_ID=""
SFCC_ORGANIZATIONID="f_ecom_0000_000"
SFCC_SECRET=""
SFCC_SHORTCODE="000123"
SFCC_SITEID="RefArch"
SITE_NAME="ACME Store"
SFCC_REVALIDATION_SECRET=""
23 changes: 0 additions & 23 deletions .eslintrc.js

This file was deleted.

6 changes: 0 additions & 6 deletions .github/dependabot.yml

This file was deleted.

35 changes: 0 additions & 35 deletions .github/workflows/test.yml

This file was deleted.

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
.env*.local

# editors
.cursor
1 change: 0 additions & 1 deletion .nvmrc

This file was deleted.

3 changes: 0 additions & 3 deletions .prettierignore

This file was deleted.

6 changes: 3 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.organizeImports": true,
"source.sortMembers": true
"source.fixAll": "explicit",
"source.organizeImports": "explicit",
"source.sortMembers": "explicit"
}
}
92 changes: 41 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,76 +1,66 @@
[![Deploy with Vercel](https://vercel.com/button)](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)
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fcommerce-sfcc&env=COMPANY_NAME,NEXT_PUBLIC_VERCEL_URL,SFCC_CLIENT_ID,SFCC_ORGANIZATIONID,SFCC_SECRET,SFCC_SHORTCODE,SFCC_SITEID,SITE_NAME,SFCC_REVALIDATION_SECRET&project-name=nextjs-commerce-sfcc&repository-name=nextjs-commerce-sfcc&demo-title=ACME%20Store&demo-description=A%20high-performance%20ecommerce%20store%20built%20with%20Next.js%2C%20Vercel%2C%20and%20Salesforce%20Commerce%20Cloud&demo-url=https%3A%2F%2Fnextjs-salesforce-commerce-cloud.vercel.app%2F)

# Next.js Commerce
# Next.js Commerce + Salesforce Commerce Cloud

A Next.js 14 and App Router-ready ecommerce template featuring:
A high-perfomance, server-rendered Next.js App Router ecommerce application.

- Next.js App Router
- Optimized for SEO using Next.js's Metadata
- React Server Components (RSCs) and Suspense
- Server Actions for mutations
- Edge Runtime
- New fetching and caching paradigms
- Dynamic OG images
- Styling with Tailwind CSS
- Checkout and payments with Shopify
- Automatic light/dark mode based on system settings
This template uses React Server Components, Server Actions, _Suspense_, _useOptimistic_, _use cache_ and more.

<h3 id="v1-note"></h3>
## Providers

> Note: Looking for Next.js Commerce v1? View the [code](https://github.com/vercel/commerce/tree/v1), [demo](https://commerce-v1.vercel.store), and [release notes](https://github.com/vercel/commerce/releases/tag/v1).
This version of Next.js Commerce is integrated with Salesforce Commerce Cloud. The integration code for Salesforce Commerce Cloud can be found in the _lib/sfcc_ directory.

## Providers
For information on other commerce providers, additional details, and the core Next.js Commerce template, please refer to the official [Next.js Commerce repository](https://github.com/vercel/commerce).

## Enviroment variables

Vercel will only be actively maintaining a Shopify version [as outlined in our vision and strategy for Next.js Commerce](https://github.com/vercel/commerce/pull/966).
This project requires the following environment variables for connecting to Salesforce Commerce Cloud:

```
SFCC_ORGANIZATIONID=""
SFCC_SHORTCODE=""
SFCC_SITEID="RefArch"
SFCC_CLIENT_ID=""
SFCC_SECRET=""
SITE_NAME="ACME Store"
SFCC_REVALIDATION_SECRET=""
```

Vercel is happy to partner and work with any commerce provider to help them get a similar template up and running and listed below. Alternative providers should be able to fork this repository and swap out the `lib/shopify` file with their own implementation while leaving the rest of the template mostly unchanged.
- _SFCC_ORGANIZATIONID_: Salesforce Commerce Cloud Organization ID
- _SFCC_SHORTCODE_: Salesforce Commerce Cloud instance short code
- _SFCC_SITEID_: ID of the target site
- _SFCC_CLIENT_ID_: SLAS API Client ID
- _SFCC_SECRET_: SLAS API Client Secret
- _SITE_NAME_: User-defined name for the site
- _SFCC_REVALIDATION_SECRET_: User-defined string for on-demand revalidation

- Shopify (this repository)
- [BigCommerce](https://github.com/bigcommerce/nextjs-commerce) ([Demo](https://next-commerce-v2.vercel.app/))
- [Medusa](https://github.com/medusajs/vercel-commerce) ([Demo](https://medusa-nextjs-commerce.vercel.app/))
- [Saleor](https://github.com/saleor/nextjs-commerce) ([Demo](https://saleor-commerce.vercel.app/))
- [Shopware](https://github.com/shopwareLabs/vercel-commerce) ([Demo](https://shopware-vercel-commerce-react.vercel.app/))
- [Swell](https://github.com/swellstores/verswell-commerce) ([Demo](https://verswell-commerce.vercel.app/))
- [Umbraco](https://github.com/umbraco/Umbraco.VercelCommerce.Demo) ([Demo](https://vercel-commerce-demo.umbraco.com/))
- [Wix](https://github.com/wix/nextjs-commerce) ([Demo](https://wix-nextjs-commerce.vercel.app/))
Please refer to the official Salesforce Commerce API documentation for details on how to retrieve these values:

> Note: Providers, if you are looking to use similar products for your demo, you can [download these assets](https://drive.google.com/file/d/1q_bKerjrwZgHwCw0ovfUMW6He9VtepO_/view?usp=sharing).
- [Base URL Configuration](https://developer.salesforce.com/docs/commerce/commerce-api/guide/base-url.html)
- [SLAS Authorization](https://developer.salesforce.com/docs/commerce/commerce-api/guide/authorization-for-shopper-apis.html)

## Integrations
## Store configuration

Integrations enable upgraded or additional functionality for Next.js Commerce
This project works with a standard Salesforce Commerce Cloud _RefArch_ site with minimal modifications. However, for the homepage to display content correctly, two product categories must be created:

- [Orama](https://github.com/oramasearch/nextjs-commerce) ([Demo](https://vercel-commerce.oramasearch.com/))
- Upgrades search to include typeahead with dynamic re-rendering, vector-based similarity search, and JS-based configuration.
- Search runs entirely in the browser for smaller catalogs or on a CDN for larger.
- _hidden-homepage-carousel_: This category populates the main carousel on the homepage
- _hidden-homepage-featured-items_: This category populates the featured products section on the homepage

Create these two categories and assign products to them within Business Manager.

## Running locally

You will need to use the environment variables [defined in `.env.example`](.env.example) to run Next.js Commerce. It's recommended you use [Vercel Environment Variables](https://vercel.com/docs/concepts/projects/environment-variables) for this, but a `.env` file is all that is necessary.
You will need to use the environment variables defined in _.env.example_ to run Next.js Commerce. It's recommended you use [Vercel Environment Variables](https://vercel.com/docs/concepts/projects/environment-variables) for this, but a _.env_ file is all that is necessary.

> Note: You should not commit your `.env` file or it will expose secrets that will allow others to control your Shopify store.
> Note: You should not commit your _.env_ file or it will expose secrets that will allow others to control your Salesforce Commerce Cloud store.

1. Install Vercel CLI: `npm i -g vercel`
2. Link local instance with Vercel and GitHub accounts (creates `.vercel` directory): `vercel link`
3. Download your environment variables: `vercel env pull`
1. Install Vercel CLI: _npm i -g vercel_
2. Link local instance with Vercel and GitHub accounts (creates _.vercel_ directory): _vercel link_
3. Download your environment variables: _vercel env pull_

```bash
pnpm install
pnpm dev
```

Your app should now be running on [localhost:3000](http://localhost:3000/).

<details>
<summary>Expand if you work at Vercel and want to run locally and / or contribute</summary>

1. Run `vc link`.
1. Select the `Vercel Solutions` scope.
1. Connect to the existing `commerce-shopify` project.
1. Run `vc env pull` to get environment variables.
1. Run `pnpm dev` to ensure everything is working correctly.
</details>

## Vercel, Next.js Commerce, and Shopify Integration Guide

You can use this comprehensive [integration guide](http://vercel.com/docs/integrations/shopify) with step-by-step instructions on how to configure Shopify as a headless CMS using Next.js Commerce as your headless Shopify storefront on Vercel.
11 changes: 4 additions & 7 deletions app/[page]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import Footer from 'components/layout/footer';
import { Suspense } from 'react';
import Footer from "components/layout/footer";

export default function Layout({ children }: { children: React.ReactNode }) {
return (
<Suspense>
<>
<div className="w-full">
<div className="mx-8 max-w-2xl py-20 sm:mx-auto">
<Suspense>{children}</Suspense>
</div>
<div className="mx-8 max-w-2xl py-20 sm:mx-auto">{children}</div>
</div>
<Footer />
</Suspense>
</>
);
}
11 changes: 6 additions & 5 deletions app/[page]/opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import OpengraphImage from 'components/opengraph-image';
import { getPage } from 'lib/shopify';

export const runtime = 'edge';
import OpengraphImage from "components/opengraph-image";
import { getPage } from "lib/sfcc/content";

export default async function Image({ params }: { params: { page: string } }) {
const page = await getPage(params.page);
const page = getPage(params.page);

if (!page) return;

const title = page.seo?.title || page.title;

return await OpengraphImage({ title });
Expand Down
43 changes: 22 additions & 21 deletions app/[page]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import type { Metadata } from 'next';
import type { Metadata } from "next";

import Prose from 'components/prose';
import { getPage } from 'lib/shopify';
import { notFound } from 'next/navigation';
import Prose from "components/prose";
import { getPage } from "lib/sfcc/content";
import { notFound } from "next/navigation";

export const runtime = 'edge';

export const revalidate = 43200; // 12 hours in seconds

export async function generateMetadata({
params
}: {
params: { page: string };
export async function generateMetadata(props: {
params: Promise<{ page: string }>;
}): Promise<Metadata> {
const params = await props.params;
const page = await getPage(params.page);

if (!page) return notFound();
Expand All @@ -23,26 +18,32 @@ export async function generateMetadata({
openGraph: {
publishedTime: page.createdAt,
modifiedTime: page.updatedAt,
type: 'article'
}
type: "article",
},
};
}

export default async function Page({ params }: { params: { page: string } }) {
export default async function Page(props: {
params: Promise<{ page: string }>;
}) {
const params = await props.params;
const page = await getPage(params.page);

if (!page) return notFound();

return (
<>
<h1 className="mb-8 text-5xl font-bold">{page.title}</h1>
<Prose className="mb-8" html={page.body as string} />
<Prose className="mb-8" html={page.body} />
<p className="text-sm italic">
{`This document was last updated on ${new Intl.DateTimeFormat(undefined, {
year: 'numeric',
month: 'long',
day: 'numeric'
}).format(new Date(page.updatedAt))}.`}
{`This document was last updated on ${new Intl.DateTimeFormat(
undefined,
{
year: "numeric",
month: "long",
day: "numeric",
},
).format(new Date(page.updatedAt))}.`}
</p>
</>
);
Expand Down
6 changes: 2 additions & 4 deletions app/api/revalidate/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { revalidate } from 'lib/shopify';
import { NextRequest, NextResponse } from 'next/server';

export const runtime = 'edge';
import { revalidate } from "lib/sfcc";
import { NextRequest, NextResponse } from "next/server";

export async function POST(req: NextRequest): Promise<NextResponse> {
return revalidate(req);
Expand Down
13 changes: 13 additions & 0 deletions app/checkout/(main)/information/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { InformationForm } from "@/components/checkout/information-form";
import { getCart } from "@/lib/sfcc";
import { redirect } from "next/navigation";

export default async function InformationPage() {
const cart = await getCart();

if (!cart || cart.lines.length === 0) {
redirect("/");
}

return <InformationForm />;
}
Loading