Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(templates): ecommerce template v3 #8297

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
15 changes: 15 additions & 0 deletions templates/ecommerce-3/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
COMPANY_NAME="Payload Inc."
TWITTER_CREATOR="@payloadcms"
TWITTER_SITE="https://nextjs.org/commerce"
SITE_NAME="Payload Commerce"

PAYLOAD_PUBLIC_SERVER_URL=http://localhost:3000
NEXT_PUBLIC_SERVER_URL=http://localhost:3000

# Used to preview drafts
PAYLOAD_PUBLIC_DRAFT_SECRET=demo-draft-secret
NEXT_PRIVATE_DRAFT_SECRET=demo-draft-secret

# Used to revalidate static pages
REVALIDATION_KEY=demo-revalation-key
NEXT_PRIVATE_REVALIDATION_KEY=demo-revalation-key
9 changes: 9 additions & 0 deletions templates/ecommerce-3/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
extends: 'next',
root: true,
parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
},
}
40 changes: 40 additions & 0 deletions templates/ecommerce-3/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage
.playwright

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*
!.env.example

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

media
1 change: 1 addition & 0 deletions templates/ecommerce-3/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18
3 changes: 3 additions & 0 deletions templates/ecommerce-3/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.vercel
.next
pnpm-lock.yaml
6 changes: 6 additions & 0 deletions templates/ecommerce-3/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"semi": false
}
28 changes: 28 additions & 0 deletions templates/ecommerce-3/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug server-side",
"type": "node-terminal",
"request": "launch",
"command": "pnpm dev"
},
{
"name": "Next.js: debug client-side",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000"
},
{
"name": "Next.js: debug full stack",
"type": "node-terminal",
"request": "launch",
"command": "pnpm dev",
"serverReadyAction": {
"pattern": "started server on .+, url: (https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}
9 changes: 9 additions & 0 deletions templates/ecommerce-3/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit",
"source.sortMembers": "explicit"
}
}
83 changes: 83 additions & 0 deletions templates/ecommerce-3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
[![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)

# Next.js Commerce

A Next.js 14 and App Router-ready ecommerce template featuring:

- 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

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

> 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).

## Providers

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).

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.

- Shopify (this repository)
- [BigCommerce](https://github.com/bigcommerce/nextjs-commerce) ([Demo](https://next-commerce-v2.vercel.app/))
- [Ecwid by Lightspeed](https://github.com/Ecwid/ecwid-nextjs-commerce/) ([Demo](https://ecwid-nextjs-commerce.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/))

> 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).

## Integrations

Integrations enable upgraded or additional functionality for Next.js Commerce

- [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.

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

> Note: You should not commit your `.env` file or it will expose secrets that will allow others to control your Shopify 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`

```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](https://vercel.com/docs/integrations/ecommerce/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.

## Stripe

```
stripe listen --forward-to localhost:3000/api/stripe/webhooks
```
17 changes: 17 additions & 0 deletions templates/ecommerce-3/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "src/app/(app)/globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/utilities"
}
}
25 changes: 25 additions & 0 deletions templates/ecommerce-3/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { withPayload } from '@payloadcms/next/withPayload'

import redirects from './redirects.js'

const NEXT_PUBLIC_SERVER_URL = process.env.NEXT_PUBLIC_SERVER_URL || 'http://localhost:3000'

/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
...[NEXT_PUBLIC_SERVER_URL /* 'https://example.com' */].map((item) => {
const url = new URL(item)

return {
hostname: url.hostname,
protocol: url.protocol.replace(':', ''),
}
}),
],
},
reactStrictMode: true,
redirects,
}

export default withPayload(nextConfig)
101 changes: 101 additions & 0 deletions templates/ecommerce-3/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
{
"name": "@payloadcms/template-ecommerce",
"version": "1.0.0",
"description": "Ecommerce template for Payload",
"license": "MIT",
"type": "module",
"scripts": {
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
"dev:prod": "cross-env NODE_OPTIONS=--no-deprecation rm -rf .next && pnpm build && pnpm start",
"generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",
"generate:types": "cross-env NODE_OPTIONS=--no-deprecation payload generate:types",
"ii": "cross-env NODE_OPTIONS=--no-deprecation pnpm --ignore-workspace install",
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
"lint:fix": "cross-env NODE_OPTIONS=--no-deprecation next lint --fix",
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
"reinstall": "cross-env NODE_OPTIONS=--no-deprecation rm -rf node_modules && rm pnpm-lock.yaml && pnpm --ignore-workspace install",
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
},
"dependencies": {
"@lexical/list": "0.16.1",
"@lexical/react": "0.16.1",
"@lexical/rich-text": "0.16.1",
"@lexical/utils": "0.16.1",
"@payloadcms/db-mongodb": "3.0.0-beta.107",
"@payloadcms/db-postgres": "3.0.0-beta.107",
"@payloadcms/email-nodemailer": "3.0.0-beta.107",
"@payloadcms/live-preview-react": "3.0.0-beta.107",
"@payloadcms/next": "3.0.0-beta.107",
"@payloadcms/plugin-cloud": "3.0.0-beta.107",
"@payloadcms/plugin-form-builder": "3.0.0-beta.107",
"@payloadcms/plugin-nested-docs": "3.0.0-beta.107",
"@payloadcms/plugin-redirects": "3.0.0-beta.107",
"@payloadcms/plugin-seo": "3.0.0-beta.107",
"@payloadcms/plugin-stripe": "3.0.0-beta.107",
"@payloadcms/richtext-lexical": "3.0.0-beta.107",
"@payloadcms/translations": "3.0.0-beta.107",
"@payloadcms/ui": "3.0.0-beta.107",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-slot": "^1.0.2",
"@stripe/react-stripe-js": "^2.7.1",
"@stripe/stripe-js": "^4.0.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"cross-env": "^7.0.3",
"dotenv": "^8.2.0",
"embla-carousel-auto-scroll": "^8.1.5",
"embla-carousel-react": "^8.1.5",
"geist": "^1.3.0",
"jsonwebtoken": "9.0.1",
"lexical": "0.17.0",
"lucide-react": "^0.378.0",
"next": "15.0.0-canary.104",
"payload": "3.0.0-beta.107",
"payload-admin-bar": "^1.0.6",
"qs-esm": "^7",
"react": "19.0.0-rc-06d0b89e-20240801",
"react-dom": "19.0.0-rc-06d0b89e-20240801",
"react-hook-form": "7.45.4",
"stripe": "^10.2.0",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@tailwindcss/container-queries": "^0.1.1",
"@tailwindcss/typography": "^0.5.12",
"@types/jsonwebtoken": "^9.0.7",
"@types/node": "20.12.7",
"@types/react": "18.2.79",
"@types/react-dom": "18.2.25",
"@vercel/git-hooks": "^1.0.0",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-config-next": "^14.2.2",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-unicorn": "^52.0.0",
"lint-staged": "^15.2.2",
"postcss": "^8.4.38",
"prettier": "3.2.5",
"prettier-plugin-tailwindcss": "^0.5.14",
"tailwindcss": "^3.4.3",
"typescript": "^5.6"
},
"packageManager": "pnpm@8.2.0",
"engines": {
"node": "^18.20.2 || >=20.9.0"
},
"pnpm": {
"overrides": {
"@types/react": "npm:types-react@19.0.0-rc.0",
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.0"
}
},
"overrides": {
"@types/react": "npm:types-react@19.0.0-rc.0",
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.0"
}
}
Loading
Loading