Skip to content

Commit

Permalink
refactor(core): cache pdp page data and metadata request
Browse files Browse the repository at this point in the history
  • Loading branch information
deini committed May 2, 2024
1 parent b30fdaf commit 0b4406b
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 55 deletions.
61 changes: 61 additions & 0 deletions apps/core/app/[locale]/(default)/product/[slug]/page-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { cache } from 'react';

import { getSessionCustomerId } from '~/auth';
import { client } from '~/client';
import { graphql, VariablesOf } from '~/client/graphql';
import { revalidate } from '~/client/revalidate-target';

import { BreadcrumbsFragment } from './_components/breadcrumbs';
import { DescriptionFragment } from './_components/description';
import { DetailsFragment } from './_components/details';
import { GalleryFragment } from './_components/gallery/fragment';
import { WarrantyFragment } from './_components/warranty';

const ProductPageQuery = graphql(
`
query ProductPageQuery($entityId: Int!, $optionValueIds: [OptionValueId!]) {
site {
product(entityId: $entityId, optionValueIds: $optionValueIds) {
...GalleryFragment
...DetailsFragment
...DescriptionFragment
...WarrantyFragment
entityId
name
defaultImage {
url: urlTemplate
altText
}
categories(first: 1) {
edges {
node {
...BreadcrumbsFragment
}
}
}
seo {
pageTitle
metaDescription
metaKeywords
}
}
}
}
`,
[BreadcrumbsFragment, GalleryFragment, DetailsFragment, DescriptionFragment, WarrantyFragment],
);

type ProductPageQueryVariables = VariablesOf<typeof ProductPageQuery>;

export const getProduct = cache(async (variables: ProductPageQueryVariables) => {
const customerId = await getSessionCustomerId();

const { data } = await client.fetch({
document: ProductPageQuery,
variables,
customerId,
fetchOptions: customerId ? { cache: 'no-store' } : { next: { revalidate } },
});

return data.site.product;
});
82 changes: 27 additions & 55 deletions apps/core/app/[locale]/(default)/product/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,30 @@ import { NextIntlClientProvider } from 'next-intl';
import { getMessages, getTranslations, unstable_setRequestLocale } from 'next-intl/server';
import { Suspense } from 'react';

import { getSessionCustomerId } from '~/auth';
import { client } from '~/client';
import { graphql } from '~/client/graphql';
import { getProduct } from '~/client/queries/get-product';
import { revalidate } from '~/client/revalidate-target';
import { LocaleType } from '~/i18n';

import { Breadcrumbs, BreadcrumbsFragment } from './_components/breadcrumbs';
import { Description, DescriptionFragment } from './_components/description';
import { Details, DetailsFragment } from './_components/details';
import { Breadcrumbs } from './_components/breadcrumbs';
import { Description } from './_components/description';
import { Details } from './_components/details';
import { Gallery } from './_components/gallery';
import { GalleryFragment } from './_components/gallery/fragment';
import { RelatedProducts } from './_components/related-products';
import { Reviews } from './_components/reviews';
import { Warranty, WarrantyFragment } from './_components/warranty';
import { Warranty } from './_components/warranty';
import { getProduct } from './page-data';

interface ProductPageProps {
params: { slug: string; locale: LocaleType };
searchParams: { [key: string]: string | string[] | undefined };
}

export async function generateMetadata({ params }: ProductPageProps): Promise<Metadata> {
export async function generateMetadata({
params,
searchParams,
}: ProductPageProps): Promise<Metadata> {
const productId = Number(params.slug);
const product = await getProduct(productId);
const optionValueIds = getOptionValueIds({ searchParams });

const product = await getProduct({ entityId: productId, optionValueIds });

if (!product) {
return {};
Expand All @@ -54,33 +54,7 @@ export async function generateMetadata({ params }: ProductPageProps): Promise<Me
};
}

const ProductPageQuery = graphql(
`
query ProductPageQuery($entityId: Int!, $optionValueIds: [OptionValueId!]) {
site {
product(entityId: $entityId, optionValueIds: $optionValueIds) {
...GalleryFragment
...DetailsFragment
...DescriptionFragment
...WarrantyFragment
entityId
categories(first: 1) {
edges {
node {
...BreadcrumbsFragment
}
}
}
}
}
}
`,
[BreadcrumbsFragment, GalleryFragment, DetailsFragment, DescriptionFragment, WarrantyFragment],
);

export default async function Product({ params, searchParams }: ProductPageProps) {
const customerId = await getSessionCustomerId();

const { locale } = params;

unstable_setRequestLocale(locale);
Expand All @@ -89,25 +63,10 @@ export default async function Product({ params, searchParams }: ProductPageProps
const messages = await getMessages({ locale });

const productId = Number(params.slug);
const { slug, ...options } = searchParams;

const optionValueIds = Object.keys(options)
.map((option) => ({
optionEntityId: Number(option),
valueEntityId: Number(searchParams[option]),
}))
.filter(
(option) => !Number.isNaN(option.optionEntityId) && !Number.isNaN(option.valueEntityId),
);

const { data } = await client.fetch({
document: ProductPageQuery,
variables: { entityId: productId, optionValueIds },
customerId,
fetchOptions: customerId ? { cache: 'no-store' } : { next: { revalidate } },
});
const optionValueIds = getOptionValueIds({ searchParams });

const product = data.site.product;
const product = await getProduct({ entityId: productId, optionValueIds });

if (!product) {
return notFound();
Expand Down Expand Up @@ -140,4 +99,17 @@ export default async function Product({ params, searchParams }: ProductPageProps
);
}

function getOptionValueIds({ searchParams }: { searchParams: ProductPageProps['searchParams'] }) {
const { slug, ...options } = searchParams;

return Object.keys(options)
.map((option) => ({
optionEntityId: Number(option),
valueEntityId: Number(searchParams[option]),
}))
.filter(
(option) => !Number.isNaN(option.optionEntityId) && !Number.isNaN(option.valueEntityId),
);
}

export const runtime = 'edge';

0 comments on commit 0b4406b

Please sign in to comment.