Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .changeset/wild-bears-open.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
"@bigcommerce/catalyst-makeswift": patch
---

Add explicit Makeswift SEO metadata support to public-facing pages. When configured in Makeswift, the SEO title and description will take priority over the default values from BigCommerce or static translations.

The following pages now support Makeswift SEO metadata:

- Home page (`/`)
- Catch-all page (`/[...rest]`)
- Product page (`/product/[slug]`)
- Brand page (`/brand/[slug]`)
- Category page (`/category/[slug]`)
- Blog list page (`/blog`)
- Blog post page (`/blog/[blogId]`)
- Search page (`/search`)
- Cart page (`/cart`)
- Compare page (`/compare`)
- Gift certificates page (`/gift-certificates`)
- Gift certificates balance page (`/gift-certificates/balance`)
- Contact webpage (`/webpages/[id]/contact`)
- Normal webpage (`/webpages/[id]/normal`)

## Migration steps

### Step 1: Add `getMakeswiftPageMetadata` function

Add the `getMakeswiftPageMetadata` function to `core/lib/makeswift/client.ts`:

```diff
+ export async function getMakeswiftPageMetadata({ path, locale }: { path: string; locale: string }) {
+ const { data: pages } = await client.getPages({
+ pathPrefix: path,
+ locale: normalizeLocale(locale),
+ siteVersion: await getSiteVersion(),
+ });
+
+ if (pages.length === 0 || !pages[0]) {
+ return null;
+ }
+
+ const { title, description } = pages[0];
+
+ return {
+ ...(title && { title }),
+ ...(description && { description }),
+ };
+ }
```

Export the function from `core/lib/makeswift/index.ts`:

```diff
export { Page } from './page';
- export { client } from './client';
+ export { client, getMakeswiftPageMetadata } from './client';
```

### Step 2: Update page metadata

Each page's `generateMetadata` function has been updated to fetch Makeswift metadata and use it as the primary source, falling back to existing values. Here's an example using the cart page:

Update `core/app/[locale]/(default)/cart/page.tsx`:

```diff
import { getPreferredCurrencyCode } from '~/lib/currency';
+ import { getMakeswiftPageMetadata } from '~/lib/makeswift';
import { Slot } from '~/lib/makeswift/slot';
```

```diff
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { locale } = await params;

const t = await getTranslations({ locale, namespace: 'Cart' });
+ const makeswiftMetadata = await getMakeswiftPageMetadata({ path: '/cart', locale });

return {
- title: t('title'),
+ title: makeswiftMetadata?.title || t('title'),
+ description: makeswiftMetadata?.description || undefined,
};
}
```

Apply the same pattern to the other pages listed above, using the appropriate path for each page (e.g., `/blog`, `/search`, `/compare`, etc.).
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const BrandPageQuery = graphql(`
site {
brand(entityId: $entityId) {
name
path
seo {
pageTitle
metaDescription
Expand Down
9 changes: 6 additions & 3 deletions core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { facetsTransformer } from '~/data-transformers/facets-transformer';
import { pageInfoTransformer } from '~/data-transformers/page-info-transformer';
import { productCardTransformer } from '~/data-transformers/product-card-transformer';
import { getPreferredCurrencyCode } from '~/lib/currency';
import { getMakeswiftPageMetadata } from '~/lib/makeswift';

import { MAX_COMPARE_LIMIT } from '../../../compare/page-data';
import { getCompareProducts as getCompareProductsData } from '../../fetch-compare-products';
Expand Down Expand Up @@ -67,7 +68,7 @@ interface Props {
}

export async function generateMetadata(props: Props): Promise<Metadata> {
const { slug } = await props.params;
const { slug, locale } = await props.params;
const customerAccessToken = await getSessionCustomerAccessToken();

const brandId = Number(slug);
Expand All @@ -78,11 +79,13 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
return notFound();
}

const makeswiftMetadata = await getMakeswiftPageMetadata({ path: brand.path, locale });

const { pageTitle, metaDescription, metaKeywords } = brand.seo;

return {
title: pageTitle || brand.name,
description: metaDescription,
title: makeswiftMetadata?.title || pageTitle || brand.name,
description: makeswiftMetadata?.description || metaDescription,
keywords: metaKeywords ? metaKeywords.split(',') : null,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const CategoryPageQuery = graphql(
category(entityId: $entityId) {
entityId
name
path
...BreadcrumbsFragment
seo {
pageTitle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { facetsTransformer } from '~/data-transformers/facets-transformer';
import { pageInfoTransformer } from '~/data-transformers/page-info-transformer';
import { productCardTransformer } from '~/data-transformers/product-card-transformer';
import { getPreferredCurrencyCode } from '~/lib/currency';
import { getMakeswiftPageMetadata } from '~/lib/makeswift';
import { Slot } from '~/lib/makeswift/slot';

import { MAX_COMPARE_LIMIT } from '../../../compare/page-data';
Expand Down Expand Up @@ -70,7 +71,7 @@ interface Props {
}

export async function generateMetadata(props: Props): Promise<Metadata> {
const { slug } = await props.params;
const { slug, locale } = await props.params;
const customerAccessToken = await getSessionCustomerAccessToken();

const categoryId = Number(slug);
Expand All @@ -81,11 +82,13 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
return notFound();
}

const makeswiftMetadata = await getMakeswiftPageMetadata({ path: category.path, locale });

const { pageTitle, metaDescription, metaKeywords } = category.seo;

return {
title: pageTitle || category.name,
description: metaDescription,
title: makeswiftMetadata?.title || pageTitle || category.name,
description: makeswiftMetadata?.description || metaDescription,
keywords: metaKeywords ? metaKeywords.split(',') : null,
};
}
Expand Down
5 changes: 4 additions & 1 deletion core/app/[locale]/(default)/(faceted)/search/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { facetsTransformer } from '~/data-transformers/facets-transformer';
import { pageInfoTransformer } from '~/data-transformers/page-info-transformer';
import { productCardTransformer } from '~/data-transformers/product-card-transformer';
import { getPreferredCurrencyCode } from '~/lib/currency';
import { getMakeswiftPageMetadata } from '~/lib/makeswift';

import { MAX_COMPARE_LIMIT } from '../../compare/page-data';
import { getCompareProducts as getCompareProductsData } from '../fetch-compare-products';
Expand Down Expand Up @@ -63,9 +64,11 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { locale } = await params;

const t = await getTranslations({ locale, namespace: 'Faceted.Search' });
const makeswiftMetadata = await getMakeswiftPageMetadata({ path: '/search', locale });

return {
title: t('title'),
title: makeswiftMetadata?.title || t('title'),
description: makeswiftMetadata?.description || undefined,
};
}

Expand Down
17 changes: 16 additions & 1 deletion core/app/[locale]/(default)/[...rest]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
import { Metadata } from 'next';

import { defaultLocale, locales } from '~/i18n/locales';
import { client, Page } from '~/lib/makeswift';
import { client, getMakeswiftPageMetadata, Page } from '~/lib/makeswift';

interface PageParams {
locale: string;
rest: string[];
}

export async function generateMetadata({
params,
}: {
params: Promise<PageParams>;
}): Promise<Metadata> {
const { rest, locale } = await params;
const path = `/${rest.join('/')}`;

const metadata = await getMakeswiftPageMetadata({ path, locale });

return metadata ?? {};
}

export async function generateStaticParams(): Promise<PageParams[]> {
const pages = await client.getPages().toArray();

Expand Down
1 change: 1 addition & 0 deletions core/app/[locale]/(default)/blog/[blogId]/page-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const BlogPageQuery = graphql(`
author
htmlBody
name
path
publishedDate {
utc
}
Expand Down
8 changes: 5 additions & 3 deletions core/app/[locale]/(default)/blog/[blogId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { cache } from 'react';

import { BlogPostContent, BlogPostContentBlogPost } from '@/vibes/soul/sections/blog-post-content';
import { Breadcrumb } from '@/vibes/soul/sections/breadcrumbs';
import { getMakeswiftPageMetadata } from '~/lib/makeswift';

import { getBlogPageData } from './page-data';

Expand All @@ -18,7 +19,7 @@ interface Props {
}

export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { blogId } = await params;
const { blogId, locale } = await params;

const variables = cachedBlogPageDataVariables(blogId);

Expand All @@ -29,11 +30,12 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
return {};
}

const makeswiftMetadata = await getMakeswiftPageMetadata({ path: blogPost.path, locale });
const { pageTitle, metaDescription, metaKeywords } = blogPost.seo;

return {
title: pageTitle || blogPost.name,
description: metaDescription,
title: makeswiftMetadata?.title || pageTitle || blogPost.name,
description: makeswiftMetadata?.description || metaDescription,
keywords: metaKeywords ? metaKeywords.split(',') : null,
};
}
Expand Down
9 changes: 6 additions & 3 deletions core/app/[locale]/(default)/blog/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { createSearchParamsCache, parseAsInteger, parseAsString } from 'nuqs/ser
import { Streamable } from '@/vibes/soul/lib/streamable';
import { FeaturedBlogPostList } from '@/vibes/soul/sections/featured-blog-post-list';
import { defaultPageInfo, pageInfoTransformer } from '~/data-transformers/page-info-transformer';
import { getMakeswiftPageMetadata } from '~/lib/makeswift';

import { getBlog, getBlogPosts } from './page-data';

Expand All @@ -29,13 +30,15 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {

const t = await getTranslations({ locale, namespace: 'Blog' });
const blog = await getBlog();
const makeswiftMetadata = await getMakeswiftPageMetadata({ path: '/blog', locale });

return {
title: blog?.name ?? t('title'),
title: makeswiftMetadata?.title || blog?.name || t('title'),
description:
blog?.description && blog.description.length > 150
makeswiftMetadata?.description ||
(blog?.description && blog.description.length > 150
? `${blog.description.substring(0, 150)}...`
: blog?.description,
: blog?.description),
};
}

Expand Down
5 changes: 4 additions & 1 deletion core/app/[locale]/(default)/cart/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Cart as CartComponent, CartEmptyState } from '@/vibes/soul/sections/car
import { CartAnalyticsProvider } from '~/app/[locale]/(default)/cart/_components/cart-analytics-provider';
import { getCartId } from '~/lib/cart';
import { getPreferredCurrencyCode } from '~/lib/currency';
import { getMakeswiftPageMetadata } from '~/lib/makeswift';
import { Slot } from '~/lib/makeswift/slot';
import { exists } from '~/lib/utils';

Expand All @@ -27,9 +28,11 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { locale } = await params;

const t = await getTranslations({ locale, namespace: 'Cart' });
const makeswiftMetadata = await getMakeswiftPageMetadata({ path: '/cart', locale });

return {
title: t('title'),
title: makeswiftMetadata?.title || t('title'),
description: makeswiftMetadata?.description || undefined,
};
}

Expand Down
5 changes: 4 additions & 1 deletion core/app/[locale]/(default)/compare/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { CompareSection } from '@/vibes/soul/sections/compare-section';
import { getSessionCustomerAccessToken } from '~/auth';
import { pricesTransformer } from '~/data-transformers/prices-transformer';
import { getPreferredCurrencyCode } from '~/lib/currency';
import { getMakeswiftPageMetadata } from '~/lib/makeswift';

import { addToCart } from './_actions/add-to-cart';
import { CompareAnalyticsProvider } from './_components/compare-analytics-provider';
Expand Down Expand Up @@ -41,9 +42,11 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { locale } = await params;

const t = await getTranslations({ locale, namespace: 'Compare' });
const makeswiftMetadata = await getMakeswiftPageMetadata({ path: '/compare', locale });

return {
title: t('title'),
title: makeswiftMetadata?.title || t('title'),
description: makeswiftMetadata?.description || undefined,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getTranslations, setRequestLocale } from 'next-intl/server';
import { GiftCertificateCheckBalanceSection } from '@/vibes/soul/sections/gift-certificate-balance-section';
import { redirect } from '~/i18n/routing';
import { getPreferredCurrencyCode } from '~/lib/currency';
import { getMakeswiftPageMetadata } from '~/lib/makeswift';

import { getGiftCertificatesData } from '../page-data';

Expand All @@ -17,9 +18,14 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { locale } = await params;

const t = await getTranslations({ locale, namespace: 'GiftCertificates' });
const makeswiftMetadata = await getMakeswiftPageMetadata({
path: '/gift-certificates/balance',
locale,
});

return {
title: t('title') || 'Gift certificates - Check balance',
title: makeswiftMetadata?.title || t('title') || 'Gift certificates - Check balance',
description: makeswiftMetadata?.description || undefined,
};
}

Expand Down
5 changes: 4 additions & 1 deletion core/app/[locale]/(default)/gift-certificates/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getFormatter, getTranslations, setRequestLocale } from 'next-intl/serve
import { GiftCertificatesSection } from '@/vibes/soul/sections/gift-certificates-section';
import { redirect } from '~/i18n/routing';
import { getPreferredCurrencyCode } from '~/lib/currency';
import { getMakeswiftPageMetadata } from '~/lib/makeswift';

import { getGiftCertificatesData } from './page-data';

Expand All @@ -15,9 +16,11 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { locale } = await params;

const t = await getTranslations({ locale, namespace: 'GiftCertificates' });
const makeswiftMetadata = await getMakeswiftPageMetadata({ path: '/gift-certificates', locale });

return {
title: t('title') || 'Gift certificates',
title: makeswiftMetadata?.title || t('title') || 'Gift certificates',
description: makeswiftMetadata?.description || undefined,
};
}

Expand Down
Loading
Loading