forked from crowetic/commerce
cleanup for PR
This commit is contained in:
parent
7f438aa67d
commit
7786d6445d
15
.vscode/launch.json
vendored
15
.vscode/launch.json
vendored
@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
// Use IntelliSense to learn about possible attributes.
|
|
||||||
// Hover to view descriptions of existing attributes.
|
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"type": "pwa-chrome",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "Launch Chrome against localhost",
|
|
||||||
"url": "http://localhost:8080",
|
|
||||||
"webRoot": "${workspaceFolder}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
231
README.md
231
README.md
@ -1,231 +0,0 @@
|
|||||||
[](https://vercel.com/new/git/external?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fcommerce&project-name=commerce&repo-name=commerce&demo-title=Next.js%20Commerce&demo-description=An%20all-in-one%20starter%20kit%20for%20high-performance%20e-commerce%20sites.&demo-url=https%3A%2F%2Fdemo.vercel.store&demo-image=https%3A%2F%2Fbigcommerce-demo-asset-ksvtgfvnd.vercel.app%2Fbigcommerce.png&integration-ids=oac_MuWZiE4jtmQ2ejZQaQ7ncuDT)
|
|
||||||
|
|
||||||
# Next.js Commerce
|
|
||||||
|
|
||||||
The all-in-one starter kit for high-performance e-commerce sites. With a few clicks, Next.js developers can clone, deploy and fully customize their own store.
|
|
||||||
Start right now at [nextjs.org/commerce](https://nextjs.org/commerce)
|
|
||||||
|
|
||||||
Demo live at: [demo.vercel.store](https://demo.vercel.store/)
|
|
||||||
|
|
||||||
- Shopify Demo: https://shopify.demo.vercel.store/
|
|
||||||
- BigCommerce Demo: https://bigcommerce.demo.vercel.store/
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- Performant by default
|
|
||||||
- SEO Ready
|
|
||||||
- Internationalization
|
|
||||||
- Responsive
|
|
||||||
- UI Components
|
|
||||||
- Theming
|
|
||||||
- Standardized Data Hooks
|
|
||||||
- Integrations - Integrate seamlessly with the most common ecommerce platforms.
|
|
||||||
- Dark Mode Support
|
|
||||||
|
|
||||||
## Integrations
|
|
||||||
|
|
||||||
Next.js Commerce integrates out-of-the-box with BigCommerce and Shopify. We plan to support all major ecommerce backends.
|
|
||||||
|
|
||||||
## 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`).
|
|
||||||
- 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
|
|
||||||
|
|
||||||
### How to change providers
|
|
||||||
|
|
||||||
Open `.env.local` and change the value of `COMMERCE_PROVIDER` to the provider you would like to use, then set the environment variables for that provider (use `.env.template` as the base).
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
Every provider defines the features that it supports under `framework/{provider}/commerce.config.json`
|
|
||||||
|
|
||||||
#### How to turn Features on and off
|
|
||||||
|
|
||||||
> NOTE: The selected provider should support the feature that you are toggling. (This means that you can't turn wishlist on if the provider doesn't support this functionality out the box)
|
|
||||||
|
|
||||||
- Open `commerce.config.json`
|
|
||||||
- You'll see a config file like this:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"features": {
|
|
||||||
"wishlist": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- Turn wishlist on by setting wishlist to true.
|
|
||||||
- Run the app and the wishlist functionality should be back on.
|
|
||||||
|
|
||||||
### How to create a new provider
|
|
||||||
|
|
||||||
Follow our docs for [Adding a new Commerce Provider](framework/commerce/new-provider.md).
|
|
||||||
|
|
||||||
If you succeeded building a provider, submit a PR with a valid demo and we'll review it asap.
|
|
||||||
|
|
||||||
## Contribute
|
|
||||||
|
|
||||||
Our commitment to Open Source can be found [here](https://vercel.com/oss).
|
|
||||||
|
|
||||||
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device.
|
|
||||||
2. Create a new branch `git checkout -b MY_BRANCH_NAME`
|
|
||||||
3. Install yarn: `npm install -g yarn`
|
|
||||||
4. Install the dependencies: `yarn`
|
|
||||||
5. Duplicate `.env.template` and rename it to `.env.local`
|
|
||||||
6. Add proper store values to `.env.local`
|
|
||||||
7. Run `yarn dev` to build and watch for code changes
|
|
||||||
|
|
||||||
## Work in progress
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
## Framework
|
|
||||||
|
|
||||||
Framework is where the data comes from. It contains mostly hook handlers and functions.
|
|
||||||
|
|
||||||
## Structure
|
|
||||||
|
|
||||||
Main folder and its exposed functions
|
|
||||||
|
|
||||||
- `product`
|
|
||||||
- usePrice
|
|
||||||
- useSearch
|
|
||||||
- getProduct
|
|
||||||
- getAllProducts
|
|
||||||
- `wishlist`
|
|
||||||
- useWishlist
|
|
||||||
- useAddItem
|
|
||||||
- useRemoveItem
|
|
||||||
- `auth`
|
|
||||||
- useLogin
|
|
||||||
- useLogout
|
|
||||||
- useSignup
|
|
||||||
- `customer`
|
|
||||||
- useCustomer
|
|
||||||
- getCustomerId
|
|
||||||
- getCustomerWistlist
|
|
||||||
- `cart`
|
|
||||||
|
|
||||||
- useCart
|
|
||||||
- useAddItem
|
|
||||||
- useRemoveItem
|
|
||||||
- useUpdateItem
|
|
||||||
|
|
||||||
- `config.json`
|
|
||||||
- README.md
|
|
||||||
|
|
||||||
#### Example of correct usage of the Commerce Framework
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { useUI } from '@components/ui'
|
|
||||||
import { useCustomer } from '@framework/customer'
|
|
||||||
import { useWishlist, useAddItem, useRemoveItem } from '@framework/wishlist'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
### How to change providers
|
|
||||||
|
|
||||||
First, update the provider selected in `commerce.config.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"provider": "bigcommerce",
|
|
||||||
"features": {
|
|
||||||
"wishlist": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, change the paths defined in `tsconfig.json` and update the `@framework` paths to point to the right folder provider:
|
|
||||||
|
|
||||||
```json
|
|
||||||
"@framework": ["framework/bigcommerce"],
|
|
||||||
"@framework/*": ["framework/bigcommerce/*"]
|
|
||||||
```
|
|
||||||
|
|
||||||
Make sure to add the environment variables required by the new provider.
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
Every provider defines the features that it supports under `framework/{provider}/commerce.config.json`
|
|
||||||
|
|
||||||
#### How to turn Features on and off
|
|
||||||
|
|
||||||
> NOTE: The selected provider should support the feature that you are toggling. (This means that you can't turn wishlist on if the provider doesn't support this functionality out the box)
|
|
||||||
|
|
||||||
- Open `commerce.config.json`
|
|
||||||
- You'll see a config file like this:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"provider": "bigcommerce",
|
|
||||||
"features": {
|
|
||||||
"wishlist": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- Turn wishlist on by setting wishlist to true.
|
|
||||||
- Run the app and the wishlist functionality should be back on.
|
|
||||||
|
|
||||||
### How to create a new provider
|
|
||||||
|
|
||||||
We'd recommend to duplicate a provider folder and push your providers SDK.
|
|
||||||
|
|
||||||
If you succeeded building a provider, submit a PR so we can all enjoy it.
|
|
||||||
|
|
||||||
## Contribute
|
|
||||||
|
|
||||||
Our commitment to Open Source can be found [here](https://vercel.com/oss).
|
|
||||||
|
|
||||||
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device.
|
|
||||||
2. Create a new branch `git checkout -b MY_BRANCH_NAME`
|
|
||||||
3. Install yarn: `npm install -g yarn`
|
|
||||||
4. Install the dependencies: `yarn`
|
|
||||||
5. Duplicate `.env.template` and rename it to `.env.local`.
|
|
||||||
6. Add proper store values to `.env.local`.
|
|
||||||
7. Run `yarn dev` to build and watch for code changes
|
|
||||||
8. The development branch is `canary` (this is the branch pull requests should be made against).
|
|
||||||
On a release, `canary` branch is rebased into `master`.
|
|
||||||
|
|
||||||
## Troubleshoot
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>I already own a BigCommerce store. What should I do?</summary>
|
|
||||||
<br>
|
|
||||||
First thing you do is: <b>set your environment variables</b>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
.env.local
|
|
||||||
|
|
||||||
```sh
|
|
||||||
BIGCOMMERCE_STOREFRONT_API_URL=<>
|
|
||||||
BIGCOMMERCE_STOREFRONT_API_TOKEN=<>
|
|
||||||
BIGCOMMERCE_STORE_API_URL=<>
|
|
||||||
BIGCOMMERCE_STORE_API_TOKEN=<>
|
|
||||||
BIGCOMMERCE_STORE_API_CLIENT_ID=<>
|
|
||||||
BIGCOMMERCE_CHANNEL_ID=<>
|
|
||||||
```
|
|
||||||
|
|
||||||
If your project was started with a "Deploy with Vercel" button, you can use Vercel's CLI to retrieve these credentials.
|
|
||||||
|
|
||||||
1. Install Vercel CLI: `npm i -g vercel`
|
|
||||||
2. Link local instance with Vercel and Github accounts (creates .vercel file): `vercel link`
|
|
||||||
3. Download your environment variables: `vercel env pull .env.local`
|
|
||||||
|
|
||||||
Next, you're free to customize the starter. More updates coming soon. Stay tuned.
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>BigCommerce shows a Coming Soon page and requests a Preview Code</summary>
|
|
||||||
<br>
|
|
||||||
After Email confirmation, Checkout should be manually enabled through BigCommerce platform. Look for "Review & test your store" section through BigCommerce's dashboard.
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
BigCommerce team has been notified and they plan to add more detailed about this subject.
|
|
||||||
</details>
|
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"features": {
|
"features": {
|
||||||
"wishlist": false,
|
"wishlist": true,
|
||||||
"customCheckout": false
|
"customCheckout": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
/**
|
|
||||||
* This file is expected to be used in next.config.js only
|
|
||||||
*/
|
|
||||||
|
|
||||||
const merge = require('deepmerge')
|
|
||||||
|
|
||||||
const PROVIDERS = ['bigcommerce', 'shopify', 'swell']
|
|
||||||
|
|
||||||
function getProviderName() {
|
|
||||||
return process.env.BIGCOMMERCE_STOREFRONT_API_URL ? 'bigcommerce' : null
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = (nextConfig = {}) => {
|
|
||||||
const commerce = nextConfig.commerce || {}
|
|
||||||
const name = commerce.provider || getProviderName()
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
throw new Error(
|
|
||||||
`The commerce provider is missing, please add a valid provider name or its environment variables`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (!PROVIDERS.includes(name)) {
|
|
||||||
throw new Error(
|
|
||||||
`The commerce provider "${name}" can't be found, please use one of "${PROVIDERS.join(
|
|
||||||
', '
|
|
||||||
)}"`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const commerceNextConfig = require(`../${name}/next.config`)
|
|
||||||
const config = merge(commerceNextConfig, nextConfig)
|
|
||||||
|
|
||||||
config.env = config.env || {}
|
|
||||||
|
|
||||||
Object.entries(config.commerce.features).forEach(([k, v]) => {
|
|
||||||
if (v) config.env[`COMMERCE_${k.toUpperCase()}_ENABLED`] = true
|
|
||||||
})
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
import Client from 'shopify-buy'
|
|
||||||
import { ShopifyConfig } from '../index'
|
|
||||||
|
|
||||||
type Options = {
|
|
||||||
config: ShopifyConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
const getAllCollections = async (options: Options) => {
|
|
||||||
const { config } = options
|
|
||||||
|
|
||||||
const client = Client.buildClient({
|
|
||||||
storefrontAccessToken: config.apiToken,
|
|
||||||
domain: config.commerceUrl,
|
|
||||||
})
|
|
||||||
|
|
||||||
const res = await client.collection.fetchAllWithProducts()
|
|
||||||
|
|
||||||
return JSON.parse(JSON.stringify(res))
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getAllCollections
|
|
@ -1,25 +0,0 @@
|
|||||||
import { Page } from '../../schema'
|
|
||||||
import { ShopifyConfig, getConfig } from '..'
|
|
||||||
|
|
||||||
export type GetPageResult<T extends { page?: any } = { page?: Page }> = T
|
|
||||||
|
|
||||||
export type PageVariables = {
|
|
||||||
id: string
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getPage({
|
|
||||||
url,
|
|
||||||
variables,
|
|
||||||
config,
|
|
||||||
preview,
|
|
||||||
}: {
|
|
||||||
url?: string
|
|
||||||
variables: PageVariables
|
|
||||||
config?: ShopifyConfig
|
|
||||||
preview?: boolean
|
|
||||||
}): Promise<GetPageResult> {
|
|
||||||
config = getConfig(config)
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getPage
|
|
@ -22,6 +22,7 @@ export const handler: SWRHook<
|
|||||||
},
|
},
|
||||||
async fetcher({ input: { cartId: checkoutId }, options, fetch }) {
|
async fetcher({ input: { cartId: checkoutId }, options, fetch }) {
|
||||||
let checkout
|
let checkout
|
||||||
|
|
||||||
if (checkoutId) {
|
if (checkoutId) {
|
||||||
const data = await fetch({
|
const data = await fetch({
|
||||||
...options,
|
...options,
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
import {
|
|
||||||
SHOPIFY_CHECKOUT_ID_COOKIE,
|
|
||||||
SHOPIFY_CHECKOUT_URL_COOKIE,
|
|
||||||
SHOPIFY_COOKIE_EXPIRE,
|
|
||||||
} from '../../const'
|
|
||||||
|
|
||||||
import checkoutCreateMutation from '../../utils/mutations/checkout-create'
|
|
||||||
import Cookies from 'js-cookie'
|
|
||||||
|
|
||||||
export const checkoutCreate = async (fetch: any) => {
|
|
||||||
const data = await fetch({
|
|
||||||
query: checkoutCreateMutation,
|
|
||||||
})
|
|
||||||
|
|
||||||
const checkout = data.checkoutCreate?.checkout
|
|
||||||
const checkoutId = checkout?.id
|
|
||||||
|
|
||||||
if (checkoutId) {
|
|
||||||
const options = {
|
|
||||||
expires: SHOPIFY_COOKIE_EXPIRE,
|
|
||||||
}
|
|
||||||
Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId, options)
|
|
||||||
Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
return checkout
|
|
||||||
}
|
|
||||||
|
|
||||||
export default checkoutCreate
|
|
@ -1,42 +0,0 @@
|
|||||||
import { Cart } from '../../types'
|
|
||||||
import { CommerceError, ValidationError } from '@commerce/utils/errors'
|
|
||||||
|
|
||||||
import {
|
|
||||||
CheckoutLineItemsAddPayload,
|
|
||||||
CheckoutLineItemsRemovePayload,
|
|
||||||
CheckoutLineItemsUpdatePayload,
|
|
||||||
Maybe,
|
|
||||||
} from '../../schema'
|
|
||||||
import { normalizeCart } from '../../utils'
|
|
||||||
|
|
||||||
export type CheckoutPayload =
|
|
||||||
| CheckoutLineItemsAddPayload
|
|
||||||
| CheckoutLineItemsUpdatePayload
|
|
||||||
| CheckoutLineItemsRemovePayload
|
|
||||||
|
|
||||||
const checkoutToCart = (checkoutPayload?: Maybe<CheckoutPayload>): Cart => {
|
|
||||||
if (!checkoutPayload) {
|
|
||||||
throw new CommerceError({
|
|
||||||
message: 'Invalid response from Shopify',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const checkout = checkoutPayload?.checkout
|
|
||||||
const userErrors = checkoutPayload?.userErrors
|
|
||||||
|
|
||||||
if (userErrors && userErrors.length) {
|
|
||||||
throw new ValidationError({
|
|
||||||
message: userErrors[0].message,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!checkout) {
|
|
||||||
throw new CommerceError({
|
|
||||||
message: 'Invalid response from Shopify',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return normalizeCart(checkout)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default checkoutToCart
|
|
@ -1,31 +0,0 @@
|
|||||||
import { HookFetcherFn } from '@commerce/utils/types'
|
|
||||||
import { Cart } from '@commerce/types'
|
|
||||||
import { checkoutCreate, checkoutToCart } from '.'
|
|
||||||
import { FetchCartInput } from '@commerce/cart/use-cart'
|
|
||||||
|
|
||||||
const fetcher: HookFetcherFn<Cart | null, FetchCartInput> = async ({
|
|
||||||
options,
|
|
||||||
input: { cartId: checkoutId },
|
|
||||||
fetch,
|
|
||||||
}) => {
|
|
||||||
let checkout
|
|
||||||
|
|
||||||
if (checkoutId) {
|
|
||||||
const data = await fetch({
|
|
||||||
...options,
|
|
||||||
variables: {
|
|
||||||
checkoutId,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
checkout = data.node
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkout?.completedAt || !checkoutId) {
|
|
||||||
checkout = await checkoutCreate(fetch)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Fix this type
|
|
||||||
return checkoutToCart({ checkout } as any)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default fetcher
|
|
@ -1,2 +0,0 @@
|
|||||||
export { default as checkoutToCart } from './checkout-to-cart'
|
|
||||||
export { default as checkoutCreate } from './checkout-create'
|
|
@ -1,13 +0,0 @@
|
|||||||
export const getCheckoutIdFromStorage = (token: string) => {
|
|
||||||
if (window && window.sessionStorage) {
|
|
||||||
return window.sessionStorage.getItem(token)
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
export const setCheckoutIdInStorage = (token: string, id: string | number) => {
|
|
||||||
if (window && window.sessionStorage) {
|
|
||||||
return window.sessionStorage.setItem(token, id + '')
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,260 +0,0 @@
|
|||||||
## Table of Contents
|
|
||||||
|
|
||||||
- [Getting Started](#getting-started)
|
|
||||||
- [Modifications](#modifications)
|
|
||||||
- [Adding item to Cart](#adding-item-to-cart)
|
|
||||||
- [Proceed to Checkout](#proceed-to-checkout)
|
|
||||||
- [General Usage](#general-usage)
|
|
||||||
- [CommerceProvider](#commerceprovider)
|
|
||||||
- [useCommerce](#usecommerce)
|
|
||||||
- [Hooks](#hooks)
|
|
||||||
- [usePrice](#useprice)
|
|
||||||
- [useAddItem](#useadditem)
|
|
||||||
- [useRemoveItem](#useremoveitem)
|
|
||||||
- [useUpdateItem](#useupdateitem)
|
|
||||||
- [APIs](#apis)
|
|
||||||
- [getProduct](#getproduct)
|
|
||||||
- [getAllProducts](#getallproducts)
|
|
||||||
- [getAllCollections](#getallcollections)
|
|
||||||
- [getAllPages](#getallpages)
|
|
||||||
|
|
||||||
# Shopify Storefront Data Hooks
|
|
||||||
|
|
||||||
Collection of hooks and data fetching functions to integrate Shopify in a React application. Designed to work with [Next.js Commerce](https://demo.vercel.store/).
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
1. Install dependencies:
|
|
||||||
|
|
||||||
```
|
|
||||||
yarn install shopify-buy
|
|
||||||
yarn install -D @types/shopify-buy
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Environment variables need to be set:
|
|
||||||
|
|
||||||
```
|
|
||||||
SHOPIFY_STORE_DOMAIN=
|
|
||||||
SHOPIFY_STOREFRONT_ACCESS_TOKEN=
|
|
||||||
NEXT_PUBLIC_SWELL_STORE_DOMAIN=
|
|
||||||
NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN=
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Point the framework to `shopify` by updating `tsconfig.json`:
|
|
||||||
|
|
||||||
```
|
|
||||||
"@framework/*": ["framework/shopify/*"],
|
|
||||||
"@framework": ["framework/shopify"]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Modifications
|
|
||||||
|
|
||||||
These modifications are temporarily until contributions are made to remove them.
|
|
||||||
|
|
||||||
#### Adding item to Cart
|
|
||||||
|
|
||||||
```js
|
|
||||||
// components/product/ProductView/ProductView.tsx
|
|
||||||
const ProductView: FC<Props> = ({ product }) => {
|
|
||||||
const addToCart = async () => {
|
|
||||||
setLoading(true)
|
|
||||||
try {
|
|
||||||
await addItem({
|
|
||||||
productId: product.id,
|
|
||||||
variantId: variant ? variant.id : product.variants[0].id,
|
|
||||||
})
|
|
||||||
openSidebar()
|
|
||||||
setLoading(false)
|
|
||||||
} catch (err) {
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Proceed to Checkout
|
|
||||||
|
|
||||||
```js
|
|
||||||
// components/cart/CartSidebarView/CartSidebarView.tsx
|
|
||||||
import { useCommerce } from '@framework'
|
|
||||||
|
|
||||||
const CartSidebarView: FC = () => {
|
|
||||||
const { checkout } = useCommerce()
|
|
||||||
return (
|
|
||||||
<Button href={checkout.webUrl} Component="a" width="100%">
|
|
||||||
Proceed to Checkout
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## General Usage
|
|
||||||
|
|
||||||
### CommerceProvider
|
|
||||||
|
|
||||||
Provider component that creates the commerce context for children.
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { CommerceProvider } from '@framework'
|
|
||||||
|
|
||||||
const App = ({ children }) => {
|
|
||||||
return <CommerceProvider locale={locale}>{children}</CommerceProvider>
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App
|
|
||||||
```
|
|
||||||
|
|
||||||
### useCommerce
|
|
||||||
|
|
||||||
Returns the configs that are defined in the nearest `CommerceProvider`. Also provides access to Shopify's `checkout` and `shop`.
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { useCommerce } from 'nextjs-commerce-shopify'
|
|
||||||
|
|
||||||
const { checkout, shop } = useCommerce()
|
|
||||||
```
|
|
||||||
|
|
||||||
- `checkout`: The information required to checkout items and pay ([Documentation](https://shopify.dev/docs/storefront-api/reference/checkouts/checkout)).
|
|
||||||
- `shop`: Represents a collection of the general settings and information about the shop ([Documentation](https://shopify.dev/docs/storefront-api/reference/online-store/shop/index)).
|
|
||||||
|
|
||||||
## Hooks
|
|
||||||
|
|
||||||
### usePrice
|
|
||||||
|
|
||||||
Display the product variant price according to currency and locale.
|
|
||||||
|
|
||||||
```js
|
|
||||||
import usePrice from '@framework/product/use-price'
|
|
||||||
|
|
||||||
const { price } = usePrice({
|
|
||||||
amount,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Takes in either `amount` or `variant`:
|
|
||||||
|
|
||||||
- `amount`: A price value for a particular item if the amount is known.
|
|
||||||
- `variant`: A shopify product variant. Price will be extracted from the variant.
|
|
||||||
|
|
||||||
### useAddItem
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { useAddItem } from '@framework/cart'
|
|
||||||
|
|
||||||
const AddToCartButton = ({ variantId, quantity }) => {
|
|
||||||
const addItem = useAddItem()
|
|
||||||
|
|
||||||
const addToCart = async () => {
|
|
||||||
await addItem({
|
|
||||||
variantId,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return <button onClick={addToCart}>Add To Cart</button>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### useRemoveItem
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { useRemoveItem } from '@framework/cart'
|
|
||||||
|
|
||||||
const RemoveButton = ({ item }) => {
|
|
||||||
const removeItem = useRemoveItem()
|
|
||||||
|
|
||||||
const handleRemove = async () => {
|
|
||||||
await removeItem({ id: item.id })
|
|
||||||
}
|
|
||||||
|
|
||||||
return <button onClick={handleRemove}>Remove</button>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### useUpdateItem
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { useUpdateItem } from '@framework/cart'
|
|
||||||
|
|
||||||
const CartItem = ({ item }) => {
|
|
||||||
const [quantity, setQuantity] = useState(item.quantity)
|
|
||||||
const updateItem = useUpdateItem(item)
|
|
||||||
|
|
||||||
const updateQuantity = async (e) => {
|
|
||||||
const val = e.target.value
|
|
||||||
await updateItem({ quantity: val })
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
max={99}
|
|
||||||
min={0}
|
|
||||||
value={quantity}
|
|
||||||
onChange={updateQuantity}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## APIs
|
|
||||||
|
|
||||||
Collections of APIs to fetch data from a Shopify store.
|
|
||||||
|
|
||||||
The data is fetched using the [Shopify JavaScript Buy SDK](https://github.com/Shopify/js-buy-sdk#readme). Read the [Shopify Storefront API reference](https://shopify.dev/docs/storefront-api/reference) for more information.
|
|
||||||
|
|
||||||
### getProduct
|
|
||||||
|
|
||||||
Get a single product by its `handle`.
|
|
||||||
|
|
||||||
```js
|
|
||||||
import getProduct from '@framework/product/get-product'
|
|
||||||
import { getConfig } from '@framework/api'
|
|
||||||
|
|
||||||
const config = getConfig()
|
|
||||||
|
|
||||||
const product = await getProduct({
|
|
||||||
variables: { slug },
|
|
||||||
config,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
### getAllProducts
|
|
||||||
|
|
||||||
```js
|
|
||||||
import getAllProducts from '@framework/product/get-all-products'
|
|
||||||
import { getConfig } from '@framework/api'
|
|
||||||
|
|
||||||
const config = getConfig()
|
|
||||||
|
|
||||||
const { products } = await getAllProducts({
|
|
||||||
variables: { first: 12 },
|
|
||||||
config,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
### getAllCollections
|
|
||||||
|
|
||||||
```js
|
|
||||||
import getAllCollections from '@framework/product/get-all-collections'
|
|
||||||
import { getConfig } from '@framework/api'
|
|
||||||
|
|
||||||
const config = getConfig()
|
|
||||||
|
|
||||||
const collections = await getAllCollections({
|
|
||||||
config,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
### getAllPages
|
|
||||||
|
|
||||||
```js
|
|
||||||
import getAllPages from '@framework/common/get-all-pages'
|
|
||||||
import { getConfig } from '@framework/api'
|
|
||||||
|
|
||||||
const config = getConfig()
|
|
||||||
|
|
||||||
const pages = await getAllPages({
|
|
||||||
variables: { first: 12 },
|
|
||||||
config,
|
|
||||||
})
|
|
||||||
```
|
|
@ -22,8 +22,8 @@
|
|||||||
"@components/*": ["components/*"],
|
"@components/*": ["components/*"],
|
||||||
"@commerce": ["framework/commerce"],
|
"@commerce": ["framework/commerce"],
|
||||||
"@commerce/*": ["framework/commerce/*"],
|
"@commerce/*": ["framework/commerce/*"],
|
||||||
"@framework": ["framework/swell"],
|
"@framework": ["framework/shopify"],
|
||||||
"@framework/*": ["framework/swell/*"]
|
"@framework/*": ["framework/shopify/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],
|
"include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user