mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 07:26:59 +00:00
Updated docs
This commit is contained in:
parent
5484c2abe6
commit
f1e0aa9d75
22
README.md
22
README.md
@ -35,11 +35,10 @@ Next.js Commerce integrates out-of-the-box with BigCommerce, Shopify, Swell, Sal
|
||||
|
||||
## Considerations
|
||||
|
||||
- `framework/commerce` contains all types, helpers and functions to be used as base to build a new **provider**.
|
||||
- **Providers** live under `framework`'s root folder and they will extend Next.js Commerce types and functionality (`framework/commerce`).
|
||||
- `packages/commerce` contains all types, helpers and functions to be used as base to build a new **provider**.
|
||||
- **Providers** live under `packages`'s root folder and they will extend Next.js Commerce types and functionality (`packages/commerce`).
|
||||
- We have a **Features API** to ensure feature parity between the UI and the Provider. The UI should update accordingly and no extra code should be bundled. All extra configuration for features will live under `features` in `commerce.config.json` and if needed it can also be accessed programatically.
|
||||
- Each **provider** should add its corresponding `next.config.js` and `commerce.config.json` adding specific data related to the provider. For example in case of BigCommerce, the images CDN and additional API routes.
|
||||
- **Providers don't depend on anything that's specific to the application they're used in**. They only depend on `framework/commerce`, on their own framework folder and on some dependencies included in `package.json`
|
||||
|
||||
## Configuration
|
||||
|
||||
@ -55,18 +54,9 @@ NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN=xxxxxxx.myshopify.com
|
||||
```
|
||||
|
||||
And check that the `tsconfig.json` resolves to the chosen provider:
|
||||
|
||||
```
|
||||
"@framework": ["framework/shopify"],
|
||||
"@framework/*": ["framework/shopify/*"]
|
||||
```
|
||||
|
||||
That's it!
|
||||
|
||||
### Features
|
||||
|
||||
Every provider defines the features that it supports under `framework/{provider}/commerce.config.json`
|
||||
Every provider defines the features that it supports under `packages/{provider}/src/commerce.config.json`
|
||||
|
||||
#### Features Available
|
||||
|
||||
@ -98,9 +88,7 @@ For example: Turning `cart` off will disable Cart capabilities.
|
||||
|
||||
### How to create a new provider
|
||||
|
||||
🔔 New providers are on hold [until we have a new API for commerce](https://github.com/vercel/commerce/pull/252) 🔔
|
||||
|
||||
Follow our docs for [Adding a new Commerce Provider](framework/commerce/new-provider.md).
|
||||
Follow our docs for [Adding a new Commerce Provider](packages/commerce/new-provider.md).
|
||||
|
||||
If you succeeded building a provider, submit a PR with a valid demo and we'll review it asap.
|
||||
|
||||
@ -119,7 +107,7 @@ Our commitment to Open Source can be found [here](https://vercel.com/oss).
|
||||
|
||||
We're using Github Projects to keep track of issues in progress and todo's. Here is our [Board](https://github.com/vercel/commerce/projects/1)
|
||||
|
||||
People actively working on this project: @okbel & @lfades.
|
||||
People actively working on this project: @okbel, @lfades, @dominiksipowicz, @gbibeaul.
|
||||
|
||||
## Troubleshoot
|
||||
|
||||
|
@ -9,7 +9,7 @@ With the deploy button below you'll be able to have a [BigCommerce](https://www.
|
||||
If you already have a BigCommerce account and want to use your current store, then copy the `.env.template` file in this directory to `.env.local` in the main directory (which will be ignored by Git):
|
||||
|
||||
```bash
|
||||
cp framework/bigcommerce/.env.template .env.local
|
||||
cp packages/bigcommerce/.env.template .env.local
|
||||
```
|
||||
|
||||
Then, set the environment variables in `.env.local` to match the ones from your store.
|
||||
|
@ -4,108 +4,82 @@
|
||||
|
||||
A commerce provider is a headless e-commerce platform that integrates with the [Commerce Framework](./README.md). Right now we have the following providers:
|
||||
|
||||
- Local ([framework/local](../local))
|
||||
- Shopify ([framework/shopify](../shopify))
|
||||
- Swell ([framework/swell](../swell))
|
||||
- BigCommerce ([framework/bigcommerce](../bigcommerce))
|
||||
- Vendure ([framework/vendure](../vendure))
|
||||
- Saleor ([framework/saleor](../saleor))
|
||||
- OrderCloud ([framework/ordercloud](../ordercloud))
|
||||
- Spree ([framework/spree](../spree))
|
||||
- Kibo Commerce ([framework/kibocommerce](../kibocommerce))
|
||||
- Commerce.js ([framework/commercejs](../commercejs))
|
||||
- Local ([packages/local](../local))
|
||||
- Shopify ([packages/shopify](../shopify))
|
||||
- Swell ([packages/swell](../swell))
|
||||
- BigCommerce ([packages/bigcommerce](../bigcommerce))
|
||||
- Vendure ([packages/vendure](../vendure))
|
||||
- Saleor ([packages/saleor](../saleor))
|
||||
- OrderCloud ([packages/ordercloud](../ordercloud))
|
||||
- Spree ([packages/spree](../spree))
|
||||
- Kibo Commerce ([packages/kibocommerce](../kibocommerce))
|
||||
- Commerce.js ([packages/commercejs](../commercejs))
|
||||
|
||||
Adding a commerce provider means adding a new folder in `framework` with a folder structure like the next one:
|
||||
Adding a commerce provider means adding a new folder in `packages` with a folder structure like the next one:
|
||||
|
||||
- `api`
|
||||
- index.ts
|
||||
- `product`
|
||||
- usePrice
|
||||
- useSearch
|
||||
- getProduct
|
||||
- getAllProducts
|
||||
- `wishlist`
|
||||
- useWishlist
|
||||
- useAddItem
|
||||
- useRemoveItem
|
||||
- `auth`
|
||||
- useLogin
|
||||
- useLogout
|
||||
- useSignup
|
||||
- `customer`
|
||||
- useCustomer
|
||||
- getCustomerId
|
||||
- getCustomerWistlist
|
||||
- `cart`
|
||||
- useCart
|
||||
- useAddItem
|
||||
- useRemoveItem
|
||||
- useUpdateItem
|
||||
- `src`
|
||||
- `api`
|
||||
- index.ts
|
||||
- `product`
|
||||
- usePrice
|
||||
- useSearch
|
||||
- getProduct
|
||||
- getAllProducts
|
||||
- `wishlist`
|
||||
- useWishlist
|
||||
- useAddItem
|
||||
- useRemoveItem
|
||||
- `auth`
|
||||
- useLogin
|
||||
- useLogout
|
||||
- useSignup
|
||||
- `customer`
|
||||
- useCustomer
|
||||
- getCustomerId
|
||||
- getCustomerWistlist
|
||||
- `cart`
|
||||
- useCart
|
||||
- useAddItem
|
||||
- useRemoveItem
|
||||
- useUpdateItem
|
||||
- `index.ts`
|
||||
- `provider.ts`
|
||||
- `commerce.config.json`
|
||||
- `next.config.cjs`
|
||||
- `package.json`
|
||||
- `tsconfig.json`
|
||||
- `env.template`
|
||||
- `index.ts`
|
||||
- `provider.ts`
|
||||
- `commerce.config.json`
|
||||
- `next.config.js`
|
||||
- `README.md`
|
||||
|
||||
`provider.ts` exports a provider object with handlers for the [Commerce Hooks](./README.md#commerce-hooks) and `api/index.ts` exports a Node.js provider for the [Commerce API](./README.md#commerce-api)
|
||||
|
||||
> **Important:** We use TypeScript for every provider and expect its usage for every new one.
|
||||
|
||||
The app imports from the provider directly instead of the core commerce folder (`framework/commerce`), but all providers are interchangeable and to achieve it every provider always has to implement the core types and helpers.
|
||||
|
||||
The provider folder should only depend on `framework/commerce` and dependencies in the main `package.json`. In the future we'll move the `framework` folder to a package that can be shared easily for multiple apps.
|
||||
The app imports from the provider directly instead of the core commerce folder (`packages/commerce`), but all providers are interchangeable and to achieve it every provider always has to implement the core types and helpers.
|
||||
|
||||
## Updating the list of known providers
|
||||
|
||||
Open [./config.js](./config.js) and add the provider name to the list in `PROVIDERS`.
|
||||
Open [/site/commerce-config.js](/site/commerce-config.js) and add the provider name to the list in `PROVIDERS`.
|
||||
|
||||
Then, open [/.env.template](/.env.template) and add the provider name in the first line.
|
||||
Then, open [/site/.env.template](/site/.env.template) and add the provider name to the list there too.
|
||||
|
||||
## Adding the provider hooks
|
||||
|
||||
Using BigCommerce as an example. The first thing to do is export a `CommerceProvider` component that includes a `provider` object with all the handlers that can be used for hooks:
|
||||
|
||||
```tsx
|
||||
import type { ReactNode } from 'react'
|
||||
import {
|
||||
CommerceConfig,
|
||||
CommerceProvider as CoreCommerceProvider,
|
||||
useCommerce as useCoreCommerce,
|
||||
} from '@commerce'
|
||||
import { bigcommerceProvider } from './provider'
|
||||
import type { BigcommerceProvider } from './provider'
|
||||
import { getCommerceProvider, useCommerce as useCoreCommerce } from '@vercel/commerce'
|
||||
import { bigcommerceProvider, BigcommerceProvider } from './provider'
|
||||
|
||||
export { bigcommerceProvider }
|
||||
export type { BigcommerceProvider }
|
||||
|
||||
export const bigcommerceConfig: CommerceConfig = {
|
||||
locale: 'en-us',
|
||||
cartCookie: 'bc_cartId',
|
||||
}
|
||||
|
||||
export type BigcommerceConfig = Partial<CommerceConfig>
|
||||
|
||||
export type BigcommerceProps = {
|
||||
children?: ReactNode
|
||||
locale: string
|
||||
} & BigcommerceConfig
|
||||
|
||||
export function CommerceProvider({ children, ...config }: BigcommerceProps) {
|
||||
return (
|
||||
<CoreCommerceProvider
|
||||
provider={bigcommerceProvider}
|
||||
config={{ ...bigcommerceConfig, ...config }}
|
||||
>
|
||||
{children}
|
||||
</CoreCommerceProvider>
|
||||
)
|
||||
}
|
||||
export const CommerceProvider = getCommerceProvider(bigcommerceProvider)
|
||||
|
||||
export const useCommerce = () => useCoreCommerce<BigcommerceProvider>()
|
||||
```
|
||||
|
||||
The exported types and components extend from the core ones exported by `@commerce`, which refers to `framework/commerce`.
|
||||
The exported types and components extend from the core ones exported by `@vercel/commerce`, which refers to `packages/commerce`.
|
||||
|
||||
The `bigcommerceProvider` object looks like this:
|
||||
|
||||
@ -146,33 +120,23 @@ export const bigcommerceProvider = {
|
||||
export type BigcommerceProvider = typeof bigcommerceProvider
|
||||
```
|
||||
|
||||
The provider object, in this case `bigcommerceProvider`, has to match the `Provider` type defined in [framework/commerce](./index.ts).
|
||||
The provider object, in this case `bigcommerceProvider`, has to match the `Provider` type defined in [packages/commerce](./src/index.tsx).
|
||||
|
||||
A hook handler, like `useCart`, looks like this:
|
||||
|
||||
```tsx
|
||||
import { useMemo } from 'react'
|
||||
import { SWRHook } from '@commerce/utils/types'
|
||||
import useCart, { UseCart, FetchCartInput } from '@commerce/cart/use-cart'
|
||||
import { normalizeCart } from '../lib/normalize'
|
||||
import type { Cart } from '../types'
|
||||
import { SWRHook } from '@vercel/commerce/utils/types'
|
||||
import useCart, { UseCart } from '@vercel/commerce/cart/use-cart'
|
||||
import type { GetCartHook } from '@vercel/commerce/types/cart'
|
||||
|
||||
export default useCart as UseCart<typeof handler>
|
||||
|
||||
export const handler: SWRHook<
|
||||
Cart | null,
|
||||
{},
|
||||
FetchCartInput,
|
||||
{ isEmpty?: boolean }
|
||||
> = {
|
||||
export const handler: SWRHook<GetCartHook> = {
|
||||
fetchOptions: {
|
||||
url: '/api/cart',
|
||||
method: 'GET',
|
||||
},
|
||||
async fetcher({ input: { cartId }, options, fetch }) {
|
||||
const data = cartId ? await fetch(options) : null
|
||||
return data && normalizeCart(data)
|
||||
},
|
||||
useHook:
|
||||
({ useData }) =>
|
||||
(input) => {
|
||||
@ -200,21 +164,15 @@ In the case of data fetching hooks like `useCart` each handler has to implement
|
||||
|
||||
```tsx
|
||||
import { useCallback } from 'react'
|
||||
import type { MutationHook } from '@commerce/utils/types'
|
||||
import { CommerceError } from '@commerce/utils/errors'
|
||||
import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item'
|
||||
import { normalizeCart } from '../lib/normalize'
|
||||
import type {
|
||||
Cart,
|
||||
BigcommerceCart,
|
||||
CartItemBody,
|
||||
AddCartItemBody,
|
||||
} from '../types'
|
||||
import type { MutationHook } from '@vercel/commerce/utils/types'
|
||||
import { CommerceError } from '@vercel/commerce/utils/errors'
|
||||
import useAddItem, { UseAddItem } from '@vercel/commerce/cart/use-add-item'
|
||||
import type { AddItemHook } from '@vercel/commerce/types/cart'
|
||||
import useCart from './use-cart'
|
||||
|
||||
export default useAddItem as UseAddItem<typeof handler>
|
||||
|
||||
export const handler: MutationHook<Cart, {}, CartItemBody> = {
|
||||
export const handler: MutationHook<AddItemHook> = {
|
||||
fetchOptions: {
|
||||
url: '/api/cart',
|
||||
method: 'POST',
|
||||
@ -229,12 +187,12 @@ export const handler: MutationHook<Cart, {}, CartItemBody> = {
|
||||
})
|
||||
}
|
||||
|
||||
const data = await fetch<BigcommerceCart, AddCartItemBody>({
|
||||
const data = await fetch({
|
||||
...options,
|
||||
body: { item },
|
||||
})
|
||||
|
||||
return normalizeCart(data)
|
||||
return data
|
||||
},
|
||||
useHook:
|
||||
({ fetch }) =>
|
||||
@ -276,9 +234,3 @@ When creating a PR for a new provider, include this list in the PR description a
|
||||
* [ ] Custom checkout
|
||||
* [ ] Typing (in progress)
|
||||
* [ ] Tests
|
||||
|
||||
## Adding the Node.js provider API
|
||||
|
||||
TODO
|
||||
|
||||
> The commerce API is currently going through a refactor in https://github.com/vercel/commerce/pull/252 - We'll update the docs once the API is released.
|
||||
|
@ -7,7 +7,7 @@ To use this provider you must have a [Commerce.js account](https://commercejs.co
|
||||
Next, copy the `.env.template` file in this directory to `.env.local` in the main directory (which will be ignored by Git):
|
||||
|
||||
```bash
|
||||
cp framework/commercejs/.env.template .env.local
|
||||
cp packages/commercejs/.env.template .env.local
|
||||
```
|
||||
|
||||
Then, set the environment variables in `.env.local` to match the ones from your store. You'll need your Commerce.js public API key, which can be found in your Commerce.js dashboard in the `Developer -> API keys` section.
|
||||
|
@ -3,7 +3,7 @@
|
||||
If you already have a Kibo Commerce account and want to use your current store, then copy the `.env.template` file in this directory to `.env.local` in the main directory (which will be ignored by Git):
|
||||
|
||||
```bash
|
||||
cp framework/kibocommerce/.env.template .env.local
|
||||
cp packages/kibocommerce/.env.template .env.local
|
||||
```
|
||||
|
||||
Then, set the environment variables in `.env.local` to match the ones from your store.
|
||||
@ -22,7 +22,7 @@ KIBO_AUTH_URL='https://home.mozu.com'
|
||||
- `KIBO_CART_COOKIE` - configurable cookie name for cart.
|
||||
- `KIBO_CUSTOMER_COOKIE` - configurable cookie name for shopper identifier/authentication cookie
|
||||
- `KIBO_CLIENT_ID` - Unique Application (Client) ID of your Application
|
||||
- `KIBO_SHARED_SECRET` - Secret API key used to authenticate application/client id.
|
||||
- `KIBO_SHARED_SECRET` - Secret API key used to authenticate application/client id.
|
||||
|
||||
|
||||
Your Kibo Client ID and Shared Secret can be found from your [Kibo eCommerce Dev Center](https://mozu.com/login)
|
||||
|
@ -9,7 +9,7 @@ This provider requires Saleor **3.x** or higher.
|
||||
Copy the `.env.template` file in this directory to `.env.local` in the main directory (which will be ignored by Git):
|
||||
|
||||
```bash
|
||||
cp framework/saleor/.env.template .env.local
|
||||
cp packages/saleor/.env.template .env.local
|
||||
```
|
||||
|
||||
Then, set the environment following variables in your `.env.local`. Both, `NEXT_PUBLIC_SALEOR_API_URL` and `COMMERCE_IMAGE_HOST` must point to your own Saleor instance.
|
||||
|
@ -7,7 +7,7 @@ Before getting started, a [Shopify](https://www.shopify.com/) account and store
|
||||
Next, copy the `.env.template` file in this directory to `.env.local` in the main directory (which will be ignored by Git):
|
||||
|
||||
```bash
|
||||
cp framework/shopify/.env.template .env.local
|
||||
cp packages/shopify/.env.template .env.local
|
||||
```
|
||||
|
||||
Then, set the environment variables in `.env.local` to match the ones from your store.
|
||||
|
@ -12,10 +12,10 @@ An integration of [Spree Commerce](https://spreecommerce.org/) within NextJS Com
|
||||
|
||||
1. Setup Nextjs Commerce - [instructions for setting up NextJS Commerce][2].
|
||||
|
||||
1. Copy the `.env.template` file in this directory (`/framework/spree`) to `.env.local` in the main directory
|
||||
1. Copy the `.env.template` file in this directory (`/packages/spree`) to `.env.local` in the main directory
|
||||
|
||||
```bash
|
||||
cp framework/spree/.env.template .env.local
|
||||
cp packages/spree/.env.template .env.local
|
||||
```
|
||||
|
||||
1. Set `NEXT_PUBLIC_SPREE_CATEGORIES_TAXONOMY_PERMALINK` and `NEXT_PUBLIC_SPREE_BRANDS_TAXONOMY_PERMALINK` environment variables:
|
||||
|
@ -28,8 +28,10 @@ This provider makes use of GraphQL code generation. The [schema.graphql](./schem
|
||||
|
||||
When developing the provider, changes to any GraphQL operations should be followed by re-generation of the types and schema files:
|
||||
|
||||
From the project root dir, run
|
||||
From the package dir, run
|
||||
|
||||
```sh
|
||||
graphql-codegen --config ./framework/vendure/codegen.json
|
||||
yarn generate
|
||||
# or
|
||||
npm run generate
|
||||
```
|
||||
|
Loading…
x
Reference in New Issue
Block a user