forked from crowetic/commerce
Added products paths to getStaticPaths
This commit is contained in:
parent
ca24a53cbf
commit
390b2c3303
54
lib/bigcommerce/api/operations/get-all-product-paths.ts
Normal file
54
lib/bigcommerce/api/operations/get-all-product-paths.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import type { GetAllProductPathsQuery } from 'lib/bigcommerce/schema';
|
||||||
|
import type { RecursivePartial, RecursiveRequired } from '../utils/types';
|
||||||
|
import { BigcommerceConfig, getConfig } from '..';
|
||||||
|
|
||||||
|
export const getAllProductPathsQuery = /* GraphQL */ `
|
||||||
|
query getAllProductPaths {
|
||||||
|
site {
|
||||||
|
products {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export interface GetAllProductPathsResult<T> {
|
||||||
|
products: T extends GetAllProductPathsQuery
|
||||||
|
? NonNullable<T['site']['products']['edges']>
|
||||||
|
: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAllProductPaths(opts?: {
|
||||||
|
query?: string;
|
||||||
|
config?: BigcommerceConfig;
|
||||||
|
}): Promise<GetAllProductPathsResult<GetAllProductPathsQuery>>;
|
||||||
|
|
||||||
|
async function getAllProductPaths<T, V = any>(opts: {
|
||||||
|
query: string;
|
||||||
|
config?: BigcommerceConfig;
|
||||||
|
}): Promise<GetAllProductPathsResult<T>>;
|
||||||
|
|
||||||
|
async function getAllProductPaths({
|
||||||
|
query = getAllProductPathsQuery,
|
||||||
|
config = getConfig(),
|
||||||
|
}: {
|
||||||
|
query?: string;
|
||||||
|
config?: BigcommerceConfig;
|
||||||
|
} = {}): Promise<GetAllProductPathsResult<GetAllProductPathsQuery>> {
|
||||||
|
// RecursivePartial forces the method to check for every prop in the data, which is
|
||||||
|
// required in case there's a custom `query`
|
||||||
|
const data = await config.fetch<RecursivePartial<GetAllProductPathsQuery>>(
|
||||||
|
query
|
||||||
|
);
|
||||||
|
const products = data.site?.products?.edges;
|
||||||
|
|
||||||
|
return {
|
||||||
|
products: (products as RecursiveRequired<typeof products>) ?? [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getAllProductPaths;
|
@ -4,16 +4,11 @@ import type {
|
|||||||
} from 'lib/bigcommerce/schema';
|
} from 'lib/bigcommerce/schema';
|
||||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types';
|
import type { RecursivePartial, RecursiveRequired } from '../utils/types';
|
||||||
import { productInfoFragment } from '../fragments/product';
|
import { productInfoFragment } from '../fragments/product';
|
||||||
import {
|
import { BigcommerceConfig, getConfig, Images } from '..';
|
||||||
BigcommerceConfig,
|
|
||||||
getConfig,
|
|
||||||
Images,
|
|
||||||
ProductImageVariables,
|
|
||||||
} from '..';
|
|
||||||
|
|
||||||
export const getProductQuery = /* GraphQL */ `
|
export const getProductQuery = /* GraphQL */ `
|
||||||
query getProduct(
|
query getProduct(
|
||||||
$slug: String!
|
$path: String!
|
||||||
$imgSmallWidth: Int = 320
|
$imgSmallWidth: Int = 320
|
||||||
$imgSmallHeight: Int
|
$imgSmallHeight: Int
|
||||||
$imgMediumWidth: Int = 640
|
$imgMediumWidth: Int = 640
|
||||||
@ -24,7 +19,7 @@ export const getProductQuery = /* GraphQL */ `
|
|||||||
$imgXLHeight: Int
|
$imgXLHeight: Int
|
||||||
) {
|
) {
|
||||||
site {
|
site {
|
||||||
route(path: $slug) {
|
route(path: $path) {
|
||||||
node {
|
node {
|
||||||
__typename
|
__typename
|
||||||
... on Product {
|
... on Product {
|
||||||
@ -45,7 +40,7 @@ export interface GetProductResult<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type ProductVariables = Images &
|
export type ProductVariables = Images &
|
||||||
Omit<GetProductQueryVariables, keyof ProductImageVariables>;
|
({ path: string; slug?: never } | { path?: never; slug: string });
|
||||||
|
|
||||||
async function getProduct(opts: {
|
async function getProduct(opts: {
|
||||||
query?: string;
|
query?: string;
|
||||||
@ -61,7 +56,7 @@ async function getProduct<T, V = any>(opts: {
|
|||||||
|
|
||||||
async function getProduct({
|
async function getProduct({
|
||||||
query = getProductQuery,
|
query = getProductQuery,
|
||||||
variables: vars,
|
variables: { slug, ...vars },
|
||||||
config = getConfig(),
|
config = getConfig(),
|
||||||
}: {
|
}: {
|
||||||
query?: string;
|
query?: string;
|
||||||
@ -71,6 +66,7 @@ async function getProduct({
|
|||||||
const variables: GetProductQueryVariables = {
|
const variables: GetProductQueryVariables = {
|
||||||
...config.imageVariables,
|
...config.imageVariables,
|
||||||
...vars,
|
...vars,
|
||||||
|
path: slug ? `/${slug}/` : vars.path!,
|
||||||
};
|
};
|
||||||
const data = await config.fetch<RecursivePartial<GetProductQuery>>(query, {
|
const data = await config.fetch<RecursivePartial<GetProductQuery>>(query, {
|
||||||
variables,
|
variables,
|
||||||
|
22
lib/bigcommerce/schema.d.ts
vendored
22
lib/bigcommerce/schema.d.ts
vendored
@ -1713,6 +1713,26 @@ export type ProductInfoFragment = (
|
|||||||
) }
|
) }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export type GetAllProductPathsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
|
export type GetAllProductPathsQuery = (
|
||||||
|
{ __typename?: 'Query' }
|
||||||
|
& { site: (
|
||||||
|
{ __typename?: 'Site' }
|
||||||
|
& { products: (
|
||||||
|
{ __typename?: 'ProductConnection' }
|
||||||
|
& { edges?: Maybe<Array<Maybe<(
|
||||||
|
{ __typename?: 'ProductEdge' }
|
||||||
|
& { node: (
|
||||||
|
{ __typename?: 'Product' }
|
||||||
|
& Pick<Product, 'path'>
|
||||||
|
) }
|
||||||
|
)>>> }
|
||||||
|
) }
|
||||||
|
) }
|
||||||
|
);
|
||||||
|
|
||||||
export type GetAllProductsQueryVariables = Exact<{
|
export type GetAllProductsQueryVariables = Exact<{
|
||||||
first?: Maybe<Scalars['Int']>;
|
first?: Maybe<Scalars['Int']>;
|
||||||
imgSmallWidth?: Maybe<Scalars['Int']>;
|
imgSmallWidth?: Maybe<Scalars['Int']>;
|
||||||
@ -1748,7 +1768,7 @@ export type GetAllProductsQuery = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
export type GetProductQueryVariables = Exact<{
|
export type GetProductQueryVariables = Exact<{
|
||||||
slug: Scalars['String'];
|
path: Scalars['String'];
|
||||||
imgSmallWidth?: Maybe<Scalars['Int']>;
|
imgSmallWidth?: Maybe<Scalars['Int']>;
|
||||||
imgSmallHeight?: Maybe<Scalars['Int']>;
|
imgSmallHeight?: Maybe<Scalars['Int']>;
|
||||||
imgMediumWidth?: Maybe<Scalars['Int']>;
|
imgMediumWidth?: Maybe<Scalars['Int']>;
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
import { GetStaticPropsContext, InferGetStaticPropsType } from "next";
|
import { GetStaticPropsContext, InferGetStaticPropsType } from 'next';
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from 'next/router';
|
||||||
import getProduct from "lib/bigcommerce/api/operations/get-product";
|
import getProduct from 'lib/bigcommerce/api/operations/get-product';
|
||||||
import { Layout } from "@components/core";
|
import { Layout } from '@components/core';
|
||||||
import { ProductView } from "@components/product";
|
import { ProductView } from '@components/product';
|
||||||
|
import getAllProductPaths from '@lib/bigcommerce/api/operations/get-all-product-paths';
|
||||||
|
|
||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
params,
|
params,
|
||||||
}: GetStaticPropsContext<{ slug: string }>) {
|
}: GetStaticPropsContext<{ slug: string }>) {
|
||||||
const { product } = await getProduct({ variables: { slug: params!.slug } });
|
const { product } = await getProduct({ variables: { slug: params!.slug } });
|
||||||
|
|
||||||
console.log("PRODUCT", product);
|
|
||||||
|
|
||||||
const productData = {
|
const productData = {
|
||||||
title: "T-Shirt",
|
title: 'T-Shirt',
|
||||||
description: `
|
description: `
|
||||||
Nothing undercover about this tee. Nope. This is the official Bad
|
Nothing undercover about this tee. Nope. This is the official Bad
|
||||||
Boys tee. Printed in white or black ink on Black, Brown, or Oatmeal.
|
Boys tee. Printed in white or black ink on Black, Brown, or Oatmeal.
|
||||||
@ -21,12 +19,13 @@ export async function getStaticProps({
|
|||||||
run. Printing starts when the drop ends. Reminder: Bad Boys For
|
run. Printing starts when the drop ends. Reminder: Bad Boys For
|
||||||
Life. Shipping may take 10+ days due to COVID-19.
|
Life. Shipping may take 10+ days due to COVID-19.
|
||||||
`,
|
`,
|
||||||
price: "$50",
|
price: '$50',
|
||||||
colors: ["black", "white", "pink"],
|
colors: ['black', 'white', 'pink'],
|
||||||
sizes: ["s", "m", "l", "xl", "xxl"],
|
sizes: ['s', 'm', 'l', 'xl', 'xxl'],
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
|
product,
|
||||||
productData,
|
productData,
|
||||||
},
|
},
|
||||||
revalidate: 200,
|
revalidate: 200,
|
||||||
@ -34,16 +33,24 @@ export async function getStaticProps({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
|
const { products } = await getAllProductPaths();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
paths: [],
|
paths: products.map((product) => ({
|
||||||
fallback: "unstable_blocking",
|
params: { slug: product!.node.path },
|
||||||
|
})),
|
||||||
|
fallback: 'unstable_blocking',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Home({
|
export default function Home({
|
||||||
|
product,
|
||||||
productData,
|
productData,
|
||||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||||
|
console.log('PRODUCT', product);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
{router.isFallback ? (
|
{router.isFallback ? (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user