From 2a0a13e76124dfcf921a97123c0b314569aff10e Mon Sep 17 00:00:00 2001 From: Jieren Chen Date: Mon, 23 Sep 2024 18:54:22 -0400 Subject: [PATCH] readme + clean checkout --- .env.example | 8 +++-- README.md | 74 ++++++++++++++++++-------------------- components/cart/actions.ts | 7 ++-- lib/fourthwall/index.ts | 6 ++-- lib/utils.ts | 2 +- 5 files changed, 46 insertions(+), 51 deletions(-) diff --git a/.env.example b/.env.example index 292128a6a..aeea7e24e 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,9 @@ # API specifics -NEXT_PUBLIC_FW_API_URL="https://api.staging.fourthwall.com" +NEXT_PUBLIC_FW_API_URL="https://api.fourthwall.com" # Site specifics NEXT_PUBLIC_FW_COLLECTION="launch" -NEXT_PUBLIC_FW_PUBLIC_TOKEN="" -NEXT_PUBLIC_FW_CHECKOUT="https://jieren-shop.staging.fourthwall.com" +NEXT_PUBLIC_FW_STOREFRONT_TOKEN="" +NEXT_PUBLIC_FW_CHECKOUT="https://oasis-sandbox-shop.fourthwall.com" + +NEXT_PUBLIC_VERCEL_URL="https://oasis-sandbox.vercel.app" diff --git a/README.md b/README.md index 4bb78d68e..2ff9b3431 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,38 @@ -[![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 x Fourthwall -# Next.js Commerce +[![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) A high-perfomance, server-rendered Next.js App Router ecommerce application. -This template uses React Server Components, Server Actions, `Suspense`, `useOptimistic`, and more. +## Create a store, get a storefront token -

+A storefront token is a public access token that allows you to pull product data from your Fourthwall store. To get a storefront token: -> 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). +1. [Set up a store](https://fourthwall.com/get-started) on Fourthwall. -## Providers +2. [Make some products](https://my-shop.fourthwall.com/admin/dashboard/products/all/) and [set up a collection](https://my-shop.fourthwall.com/admin/dashboard/products/collections/). -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). +3. (optional) [Style your store](https://my-shop.fourthwall.com/admin/dashboard/store-design/layout/index/) for the [checkout flow](https://docs.fourthwall.com/storefront/checkout). -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. +4. After you have signed up, [get a storefront token](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers). -- 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/)) +5. Fill out the environment variables below in .env.local. -> 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). +```bash +NEXT_PUBLIC_FW_API_URL="https://api.fourthwall.com" -## Integrations +NEXT_PUBLIC_FW_COLLECTION="" # Example: launch. This is available at the details page for the collection. See below for more details. +NEXT_PUBLIC_FW_STOREFRONT_TOKEN="" # Example: ptkn_... +NEXT_PUBLIC_FW_CHECKOUT="" # Example: vercel-shop.fourthwall.com. Used for checkout -Integrations enable upgraded or additional functionality for Next.js Commerce +NEXT_PUBLIC_VERCEL_URL="" # Example: fw-commerce.vercel.app. This is used for sitemap.xml + robots.txt. +``` -- [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. +## Develop locally -- [React Bricks](https://github.com/ReactBricks/nextjs-commerce-rb) ([Demo](https://nextjs-commerce.reactbricks.com/)) - - Edit pages, product details, and footer content visually using [React Bricks](https://www.reactbricks.com) visual headless CMS. +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.local` file is all that is necessary. -## 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 Fourthwall store. +> Note: You should not commit your `.env.local` file or it will expose secrets that will allow others to use your Fourthwall store. 1. Install Vercel CLI: `npm i -g vercel` 2. Link local instance with Vercel and GitHub accounts (creates `.vercel` directory): `vercel link` @@ -56,16 +45,21 @@ pnpm dev Your app should now be running on [localhost:3000](http://localhost:3000/). -
- Expand if you work at Vercel and want to run locally and / or contribute +## Deploying -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. -
+```bash +vercel # Initializes the project +vercel env add NEXT_PUBLIC_FW_API_URL # Will prompt you for the value +vercel env add NEXT_PUBLIC_FW_COLLECTION +vercel env add NEXT_PUBLIC_FW_STOREFRONT_TOKEN +vercel env add NEXT_PUBLIC_FW_CHECKOUT +vercel env add NEXT_PUBLIC_VERCEL_URL -## Vercel, Next.js Commerce, and Shopify Integration Guide +vercel --prod # Deploys to production +``` -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. +## Resources + +* Visit the API docs [here](https://docs.fourthwall.com/storefront). + +* How to get your [collection handle](https://docs.fourthwall.com/storefront/collection). diff --git a/components/cart/actions.ts b/components/cart/actions.ts index db0f4d40f..b52e7de0b 100644 --- a/components/cart/actions.ts +++ b/components/cart/actions.ts @@ -1,7 +1,7 @@ 'use server'; import { TAGS } from 'lib/constants'; -import { addToCart, createCart, createCheckout, getCart, removeFromCart, updateCart } from 'lib/fourthwall'; +import { addToCart, createCart, getCart, removeFromCart, updateCart } from 'lib/fourthwall'; import { revalidateTag } from 'next/cache'; import { cookies } from 'next/headers'; import { redirect } from 'next/navigation'; @@ -97,6 +97,7 @@ export async function updateItemQuantity( } export async function redirectToCheckout(currency: string) { + const CHECKOUT_URL = process.env.NEXT_PUBLIC_FW_CHECKOUT; let cartId = cookies().get('cartId')?.value; if (!cartId) { @@ -109,9 +110,7 @@ export async function redirectToCheckout(currency: string) { return 'Error fetching cart'; } - const { id } = await createCheckout(cartId, currency); - - redirect(`${process.env.FW_CHECKOUT}/checkout/${id}`); + redirect(`${CHECKOUT_URL}/checkout/?cartId=${cartId}&cartCurrency=USD`); } export async function createCartAndSetCookie() { diff --git a/lib/fourthwall/index.ts b/lib/fourthwall/index.ts index e6f875433..4f08fc90c 100644 --- a/lib/fourthwall/index.ts +++ b/lib/fourthwall/index.ts @@ -3,7 +3,7 @@ import { reshapeCart, reshapeProduct, reshapeProducts } from "./reshape"; import { FourthwallCart, FourthwallCheckout, FourthwallCollection, FourthwallProduct } from "./types"; const API_URL = process.env.NEXT_PUBLIC_FW_API_URL; -const FW_PUBLIC_TOKEN = process.env.NEXT_PUBLIC_FW_PUBLIC_TOKEN; +const STOREFRONT_TOKEN = process.env.NEXT_PUBLIC_FW_STOREFRONT_TOKEN; /** * Helpers @@ -17,7 +17,7 @@ async function fourthwallGet(url: string, options: RequestInit = {}): Promise ...options, headers: { 'Content-Type': 'application/json', - 'X-FW-Public-Token': FW_PUBLIC_TOKEN || '', + 'X-FW-Public-Token': STOREFRONT_TOKEN || '', ...options.headers } } @@ -44,7 +44,7 @@ async function fourthwallPost(url: string, data: any, options: RequestInit = ...options, headers: { 'Content-Type': 'application/json', - 'X-FW-Public-Token': FW_PUBLIC_TOKEN || '', + 'X-FW-Public-Token': STOREFRONT_TOKEN || '', ...options.headers }, body: JSON.stringify(data) diff --git a/lib/utils.ts b/lib/utils.ts index d1ff068ca..25d9bb312 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -11,7 +11,7 @@ export const ensureStartsWith = (stringToCheck: string, startsWith: string) => stringToCheck.startsWith(startsWith) ? stringToCheck : `${startsWith}${stringToCheck}`; export const validateEnvironmentVariables = () => { - const requiredEnvironmentVariables = ['NEXT_PUBLIC_FW_API_URL', 'NEXT_PUBLIC_FW_PUBLIC_TOKEN', 'NEXT_PUBLIC_FW_COLLECTION', 'NEXT_PUBLIC_FW_CHECKOUT']; + const requiredEnvironmentVariables = ['NEXT_PUBLIC_FW_API_URL', 'NEXT_PUBLIC_FW_STOREFRONT_TOKEN', 'NEXT_PUBLIC_FW_COLLECTION', 'NEXT_PUBLIC_FW_CHECKOUT', 'NEXT_PUBLIC_VERCEL_URL']; const missingEnvironmentVariables = [] as string[]; requiredEnvironmentVariables.forEach((envVar) => {