Skip to content

Commit

Permalink
update nextjs-shopify example
Browse files Browse the repository at this point in the history
  • Loading branch information
julianbenegas committed Feb 16, 2023
1 parent f656025 commit f32b924
Show file tree
Hide file tree
Showing 13 changed files with 2,476 additions and 386 deletions.
34 changes: 32 additions & 2 deletions examples/nextjs-shopify/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
## nextjs-shopify
# nextjs-shopify

Check out `/src/storefront/` to see how we hook into Shopify.
## Requirements

You'll need a Shopify Storefront App to use this example. Follow [this guide](https://help.shopify.com/en/manual/apps/app-types/custom-apps) to do so.

## Walk Through

The flow is:

1. We use `@bsmnt/sdk-gen` to hook into [Shopify's Storefront API](https://shopify.dev/docs/api/storefront) — see this in `/src/storefront/sdk-gen`
2. We use `@bsmnt/storefront-hooks` to create client side hooks that'll help us manage cart state, and more — see this in `/src/storefront/hooks`
3. We use `@bsmnt/drop` to put a drop countdown in fron of our app — see this in `/src/pages/_app`

## Development

1. Install yarn (or use whichever package manager you prefer):

```
npm install -g yarn
```

2. Install the dependencies with:

```
yarn
```

3. Start developing and watch for code changes:

```
yarn dev
```
10 changes: 10 additions & 0 deletions examples/nextjs-shopify/graphql.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require('dotenv').config()

module.exports = {
projects: {
app: {
schema: ['./src/storefront/sdk-gen/generated/graphql.schema.json'],
documents: ['./src/**/*.{graphql,gql}']
}
}
}
14 changes: 7 additions & 7 deletions examples/nextjs-shopify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@
"build:analyze": "cross-env ANALYZE=true yarn build",
"start": "next start",
"lint": "next lint",
"generate": "yarn sdk-gen generate --dir src/storefront/sdk-gen"
"generate": "yarn sdk-gen generate --dir src/storefront/sdk-gen",
"postinstall": "yarn generate"
},
"dependencies": {
"@bsmnt/drop": "*",
"@bsmnt/storefront-hooks": "*",
"next": "12.3.1",
"react": "18.2.0",
"react-dom": "18.2.0"
"next": "^13.1.6",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@bsmnt/sdk-gen": "*",
"@next/bundle-analyzer": "^12.2.5",
"@next/bundle-analyzer": "^13.1.6",
"cross-env": "^7.0.3",
"tsconfig": "*",
"typescript": "^4.8.4"
"typescript": "^4.9.5"
}
}
97 changes: 52 additions & 45 deletions examples/nextjs-shopify/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,60 @@
import Head from "next/head";
import Image from "next/image";
import styles from "../styles/Home.module.css";
import { useCartQuery } from "../storefront/hooks";
import { Fragment } from 'react'
import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
import { useCartQuery } from '../storefront/hooks'
import { GetStaticProps } from 'next'
import { storefront } from '../storefront/sdk-gen/sdk'
import { CollectionFragment } from '../storefront/sdk-gen/generated'

export default function Home() {
const { data } = useCartQuery({ createCartIfNotFound: true });
type PageProps = {
collections: Array<CollectionFragment>
}

export default function Home({ collections }: PageProps) {
const { data } = useCartQuery({ createCartIfNotFound: true })

return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<title>Next.js + Shopify example</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>

<main className={styles.main}>
<h1 className={styles.title}>
Welcome to <a href="https://nextjs.org">Next.js!</a>
Welcome to <a href="https://nextjs.org/docs">Next.js!</a> +{' '}
<a href="https://shopify.dev/docs/api/storefront">Shopify</a> example
</h1>

<p className={styles.description}>
Get started by editing{" "}
<code className={styles.code}>pages/index.js</code>
</p>

<div className={styles.grid}>
<a href="https://nextjs.org/docs" className={styles.card}>
<h2>Documentation &rarr;</h2>
<p>Find in-depth information about Next.js features and API.</p>
</a>

<a href="https://nextjs.org/learn" className={styles.card}>
<h2>Learn &rarr;</h2>
<p>Learn about Next.js in an interactive course with quizzes!</p>
</a>
<ul>
<h2>Collections</h2>
{collections.map((collection) => (
<li key={collection.id}>
<a href={`#`}>{collection.title}</a>
</li>
))}
</ul>

<a
href="https://github.com/vercel/next.js/tree/canary/examples"
className={styles.card}
>
<h2>Examples &rarr;</h2>
<p>Discover and deploy boilerplate example Next.js projects.</p>
</a>

<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
>
<h2>Deploy &rarr;</h2>
<p>
Instantly deploy your Next.js site to a public URL with Vercel.
</p>
</a>
</div>
<ul>
<h2>Products</h2>
{collections.map((collection) => (
<Fragment key={collection.id}>
{collection.products.nodes.map((product) => {
return (
<li key={product.id}>
<a href={'#'}>{product.title}</a>
</li>
)
})}
</Fragment>
))}
</ul>

<div>
<h1>Cart: </h1>
<pre>{data ? JSON.stringify(data, null, 2) : "null"}</pre>
<h2>Cart: </h2>
<pre>{data ? JSON.stringify(data, null, 2) : 'null'}</pre>
</div>
</main>

Expand All @@ -66,12 +64,21 @@ export default function Home() {
target="_blank"
rel="noopener noreferrer"
>
Powered by{" "}
Powered by{' '}
<span className={styles.logo}>
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
</span>
</a>
</footer>
</div>
);
)
}

export const getStaticProps: GetStaticProps<PageProps> = async (context) => {
const { collections } = await storefront.FetchCollections()
return {
props: {
collections: collections.nodes
}
}
}
68 changes: 35 additions & 33 deletions examples/nextjs-shopify/src/storefront/hooks/index.tsx
Original file line number Diff line number Diff line change
@@ -1,71 +1,73 @@
import { createStorefrontHooks } from "@bsmnt/storefront-hooks";
import { bsmntSdk } from "../sdk-gen/sdk";
import { createStorefrontHooks } from '@bsmnt/storefront-hooks'
import { storefront } from '../sdk-gen/sdk'

export const {
QueryClientProvider,
useCartQuery,
useAddLineItemsToCartMutation,
useOptimisticCartUpdate,
useRemoveLineItemsFromCartMutation,
useUpdateLineItemsInCartMutation,
useUpdateLineItemsInCartMutation
} = createStorefrontHooks({
cartLocalStorageKey: "example-nextjs-shopify",
cartLocalStorageKey: 'example-nextjs-shopify',
fetchers: {
fetchCart: async (cartId) => {
const { cart } = await bsmntSdk.FetchCart({ id: cartId });
if (cart === undefined) throw new Error("Request failed");
return cart;
},
const { cart } = await storefront.FetchCart({ id: cartId })
if (cart === undefined) throw new Error('Request failed')
return cart
}
},
mutators: {
addLineItemsToCart: async (cartId, lines) => {
const { cartLinesAdd } = await bsmntSdk.AddLineItem({
const { cartLinesAdd } = await storefront.AddLineItem({
cartId,
lines,
});
lines
})
return {
data: cartLinesAdd?.cart,
userErrors: cartLinesAdd?.userErrors,
};
userErrors: cartLinesAdd?.userErrors
}
},
createCart: async () => {
const { cartCreate } = await bsmntSdk.CreateCart();
const { cartCreate } = await storefront.CreateCart()
return {
data: cartCreate?.cart,
userErrors: cartCreate?.userErrors,
};
userErrors: cartCreate?.userErrors
}
},
createCartWithLines: async (lines) => {
const { cartCreate } = await bsmntSdk.CreateCartWithLines({ lines });
const { cartCreate } = await storefront.CreateCartWithLines({ lines })
return {
data: cartCreate?.cart,
userErrors: cartCreate?.userErrors,
};
userErrors: cartCreate?.userErrors
}
},
removeLineItemsFromCart: async (cartId, lineIds) => {
const { cartLinesRemove } = await bsmntSdk.RemoveLineItem({
const { cartLinesRemove } = await storefront.RemoveLineItem({
cartId,
lineIds,
});
lineIds
})
return {
data: cartLinesRemove?.cart,
userErrors: cartLinesRemove?.userErrors,
};
userErrors: cartLinesRemove?.userErrors
}
},
updateLineItemsInCart: async (cartId, lines) => {
const { cartLinesUpdate } = await bsmntSdk.UpdateLineItem({
const { cartLinesUpdate } = await storefront.UpdateLineItem({
cartId,
lines: lines.map((l) => ({
id: l.merchandiseId,
quantity: l.quantity,
attributes: l.attributes,
})),
});
attributes: l.attributes
}))
})
return {
data: cartLinesUpdate?.cart,
userErrors: cartLinesUpdate?.userErrors,
};
},
userErrors: cartLinesUpdate?.userErrors
}
}
},
createCartIfNotFound: true,
});
createCartIfNotFound: true
})

export { useProductFormHelper } from './use-product-form-helper'
Loading

0 comments on commit f32b924

Please sign in to comment.