diff --git a/.changeset/strong-penguins-rescue.md b/.changeset/strong-penguins-rescue.md new file mode 100644 index 000000000..524f55adb --- /dev/null +++ b/.changeset/strong-penguins-rescue.md @@ -0,0 +1,5 @@ +--- +"@bigcommerce/catalyst-core": patch +--- + +Localize metadata titles. diff --git a/core/app/[locale]/(default)/(auth)/change-password/page.tsx b/core/app/[locale]/(default)/(auth)/change-password/page.tsx index e490282c0..fc6e97af2 100644 --- a/core/app/[locale]/(default)/(auth)/change-password/page.tsx +++ b/core/app/[locale]/(default)/(auth)/change-password/page.tsx @@ -1,12 +1,17 @@ import { useTranslations } from 'next-intl'; +import { getTranslations } from 'next-intl/server'; import { redirect } from '~/i18n/routing'; import { ChangePasswordForm } from './_components/change-password-form'; -export const metadata = { - title: 'Change password', -}; +export async function generateMetadata() { + const t = await getTranslations('ChangePassword'); + + return { + title: t('title'), + }; +} interface Props { searchParams: { diff --git a/core/app/[locale]/(default)/(auth)/login/page.tsx b/core/app/[locale]/(default)/(auth)/login/page.tsx index a3029c55e..26fe533c0 100644 --- a/core/app/[locale]/(default)/(auth)/login/page.tsx +++ b/core/app/[locale]/(default)/(auth)/login/page.tsx @@ -1,5 +1,5 @@ import { useTranslations } from 'next-intl'; -import { unstable_setRequestLocale } from 'next-intl/server'; +import { getTranslations, unstable_setRequestLocale } from 'next-intl/server'; import { Link } from '~/components/link'; import { Button } from '~/components/ui/button'; @@ -7,9 +7,13 @@ import { locales, LocaleType } from '~/i18n/routing'; import { LoginForm } from './_components/login-form'; -export const metadata = { - title: 'Login', -}; +export async function generateMetadata() { + const t = await getTranslations('Login'); + + return { + title: t('title'), + }; +} interface Props { params: { locale: LocaleType }; diff --git a/core/app/[locale]/(default)/(auth)/register/page.tsx b/core/app/[locale]/(default)/(auth)/register/page.tsx index 846721a23..6e7852a4b 100644 --- a/core/app/[locale]/(default)/(auth)/register/page.tsx +++ b/core/app/[locale]/(default)/(auth)/register/page.tsx @@ -12,9 +12,13 @@ const FALLBACK_COUNTRY = { code: 'US', }; -export const metadata = { - title: 'Register account', -}; +export async function generateMetadata() { + const t = await getTranslations('Register'); + + return { + title: t('title'), + }; +} export default async function Register() { const t = await getTranslations('Register'); diff --git a/core/app/[locale]/(default)/(auth)/reset/page.tsx b/core/app/[locale]/(default)/(auth)/reset/page.tsx index ea9cfadbb..3495079b7 100644 --- a/core/app/[locale]/(default)/(auth)/reset/page.tsx +++ b/core/app/[locale]/(default)/(auth)/reset/page.tsx @@ -23,9 +23,13 @@ const ResetPageQuery = graphql( [ResetPasswordFormFragment], ); -export const metadata = { - title: 'Reset password', -}; +export async function generateMetadata() { + const t = await getTranslations('Reset'); + + return { + title: t('title'), + }; +} export default async function Reset() { const t = await getTranslations('Reset'); diff --git a/core/app/[locale]/(default)/(faceted)/search/page.tsx b/core/app/[locale]/(default)/(faceted)/search/page.tsx index 3fb58ad61..1cb1d97f6 100644 --- a/core/app/[locale]/(default)/(faceted)/search/page.tsx +++ b/core/app/[locale]/(default)/(faceted)/search/page.tsx @@ -9,9 +9,13 @@ import { MobileSideNav } from '../_components/mobile-side-nav'; import { SortBy } from '../_components/sort-by'; import { fetchFacetedSearch } from '../fetch-faceted-search'; -export const metadata = { - title: 'Search Results', -}; +export async function generateMetadata() { + const t = await getTranslations('Search'); + + return { + title: t('title'), + }; +} interface Props { searchParams: Record; diff --git a/core/app/[locale]/(default)/account/(tabs)/addresses/add/page.tsx b/core/app/[locale]/(default)/account/(tabs)/addresses/add/page.tsx index 22ae26a3a..26fce41db 100644 --- a/core/app/[locale]/(default)/account/(tabs)/addresses/add/page.tsx +++ b/core/app/[locale]/(default)/account/(tabs)/addresses/add/page.tsx @@ -59,9 +59,13 @@ const FALLBACK_COUNTRY = { states: [], }; -export const metadata = { - title: 'Add address', -}; +export async function generateMetadata() { + const t = await getTranslations('Account.Addresses.Add'); + + return { + title: t('title'), + }; +} export default async function AddPage() { const t = await getTranslations('Account.Addresses.Add'); diff --git a/core/app/[locale]/(default)/account/(tabs)/addresses/edit/[slug]/page.tsx b/core/app/[locale]/(default)/account/(tabs)/addresses/edit/[slug]/page.tsx index b3c2cfe18..cc1695d4e 100644 --- a/core/app/[locale]/(default)/account/(tabs)/addresses/edit/[slug]/page.tsx +++ b/core/app/[locale]/(default)/account/(tabs)/addresses/edit/[slug]/page.tsx @@ -89,9 +89,13 @@ const CustomerEditAddressQuery = graphql( export type CustomerEditAddressQueryResult = ResultOf; -export const metadata = { - title: 'Edit address', -}; +export async function generateMetadata() { + const t = await getTranslations('Account.Addresses.Edit'); + + return { + title: t('title'), + }; +} interface Props { params: { slug: string }; diff --git a/core/app/[locale]/(default)/account/(tabs)/addresses/page.tsx b/core/app/[locale]/(default)/account/(tabs)/addresses/page.tsx index 7e659dc7c..501b9ff21 100644 --- a/core/app/[locale]/(default)/account/(tabs)/addresses/page.tsx +++ b/core/app/[locale]/(default)/account/(tabs)/addresses/page.tsx @@ -1,4 +1,5 @@ import { notFound } from 'next/navigation'; +import { getTranslations } from 'next-intl/server'; import { Pagination } from '~/components/ui/pagination'; @@ -15,9 +16,13 @@ interface Props { }; } -export const metadata = { - title: 'Addresses', -}; +export async function generateMetadata() { + const t = await getTranslations('Account.Addresses'); + + return { + title: t('title'), + }; +} export default async function Addresses({ searchParams }: Props) { const { before, after } = searchParams; diff --git a/core/app/[locale]/(default)/account/(tabs)/settings/change-password/page.tsx b/core/app/[locale]/(default)/account/(tabs)/settings/change-password/page.tsx index 1102cbc97..6be6a836b 100644 --- a/core/app/[locale]/(default)/account/(tabs)/settings/change-password/page.tsx +++ b/core/app/[locale]/(default)/account/(tabs)/settings/change-password/page.tsx @@ -1,4 +1,4 @@ -import { unstable_setRequestLocale } from 'next-intl/server'; +import { getTranslations, unstable_setRequestLocale } from 'next-intl/server'; import { locales, LocaleType } from '~/i18n/routing'; @@ -6,9 +6,13 @@ import { TabHeading } from '../../_components/tab-heading'; import { ChangePasswordForm } from './_components/change-password-form'; -export const metadata = { - title: 'Change password', -}; +export async function generateMetadata() { + const t = await getTranslations('Account.Settings.ChangePassword'); + + return { + title: t('title'), + }; +} interface Props { params: { locale: LocaleType }; diff --git a/core/app/[locale]/(default)/account/(tabs)/settings/page.tsx b/core/app/[locale]/(default)/account/(tabs)/settings/page.tsx index b68827042..b8706a91e 100644 --- a/core/app/[locale]/(default)/account/(tabs)/settings/page.tsx +++ b/core/app/[locale]/(default)/account/(tabs)/settings/page.tsx @@ -1,10 +1,19 @@ import { notFound } from 'next/navigation'; +import { getTranslations } from 'next-intl/server'; import { TabHeading } from '../_components/tab-heading'; import { UpdateSettingsForm } from './_components/update-settings-form'; import { getCustomerSettingsQuery } from './page-data'; +export async function generateMetadata() { + const t = await getTranslations('Account.Settings'); + + return { + title: t('title'), + }; +} + export default async function Settings() { const customerSettings = await getCustomerSettingsQuery({ address: { filters: { entityIds: [4, 5, 6, 7] } }, diff --git a/core/app/[locale]/(default)/blog/page.tsx b/core/app/[locale]/(default)/blog/page.tsx index aae12547b..bbcdf0e4c 100644 --- a/core/app/[locale]/(default)/blog/page.tsx +++ b/core/app/[locale]/(default)/blog/page.tsx @@ -1,5 +1,6 @@ import type { Metadata } from 'next'; import { notFound } from 'next/navigation'; +import { getTranslations } from 'next-intl/server'; import { BlogPostCard } from '~/components/blog-post-card'; import { Pagination } from '~/components/ui/pagination'; @@ -13,10 +14,11 @@ interface Props { } export async function generateMetadata({ searchParams }: Props): Promise { + const t = await getTranslations('Blog'); const blogPosts = await getBlogPosts(searchParams); return { - title: blogPosts?.name ?? 'Blog', + title: blogPosts?.name ?? t('title'), description: blogPosts?.description && blogPosts.description.length > 150 ? `${blogPosts.description.substring(0, 150)}...` diff --git a/core/app/[locale]/(default)/cart/page.tsx b/core/app/[locale]/(default)/cart/page.tsx index 07728d33d..8a25d5a00 100644 --- a/core/app/[locale]/(default)/cart/page.tsx +++ b/core/app/[locale]/(default)/cart/page.tsx @@ -36,9 +36,13 @@ const CartPageQuery = graphql( [CartItemFragment, CheckoutSummaryFragment, GeographyFragment], ); -export const metadata = { - title: 'Cart', -}; +export async function generateMetadata() { + const t = await getTranslations('Cart'); + + return { + title: t('title'), + }; +} export default async function Cart() { const cartId = cookies().get('cartId')?.value; diff --git a/core/app/[locale]/(default)/compare/page.tsx b/core/app/[locale]/(default)/compare/page.tsx index 93ec3b216..a96b31362 100644 --- a/core/app/[locale]/(default)/compare/page.tsx +++ b/core/app/[locale]/(default)/compare/page.tsx @@ -81,9 +81,13 @@ const ComparePageQuery = graphql( [AddToCartFragment, PricingFragment], ); -export const metadata = { - title: 'Compare', -}; +export async function generateMetadata() { + const t = await getTranslations('Compare'); + + return { + title: t('title'), + }; +} interface Props { searchParams: Record; diff --git a/core/app/[locale]/error.tsx b/core/app/[locale]/error.tsx index a64b71f51..941dca5c1 100644 --- a/core/app/[locale]/error.tsx +++ b/core/app/[locale]/error.tsx @@ -2,8 +2,4 @@ import { lazy } from 'react'; -export const metadata = { - title: 'Error', -}; - export default lazy(() => import('./_components/error')); diff --git a/core/app/[locale]/maintenance/page.tsx b/core/app/[locale]/maintenance/page.tsx index 95b873a56..a983c25f2 100644 --- a/core/app/[locale]/maintenance/page.tsx +++ b/core/app/[locale]/maintenance/page.tsx @@ -25,9 +25,13 @@ const MaintenancePageQuery = graphql( [StoreLogoFragment], ); -export const metadata = { - title: 'Maintenance', -}; +export async function generateMetadata() { + const t = await getTranslations('Maintenance'); + + return { + title: t('title'), + }; +} const Container = ({ children }: { children: ReactNode }) => (
{children}
diff --git a/core/app/[locale]/not-found.tsx b/core/app/[locale]/not-found.tsx index 557bc0909..d131f294a 100644 --- a/core/app/[locale]/not-found.tsx +++ b/core/app/[locale]/not-found.tsx @@ -33,10 +33,6 @@ const NotFoundQuery = graphql( [HeaderFragment, FooterFragment, ProductCardFragment], ); -export const metadata = { - title: 'Not Found', -}; - export default async function NotFound() { const t = await getTranslations('NotFound'); diff --git a/core/app/[locale]/store-selector/page.tsx b/core/app/[locale]/store-selector/page.tsx index 7374268c3..c7aed281c 100644 --- a/core/app/[locale]/store-selector/page.tsx +++ b/core/app/[locale]/store-selector/page.tsx @@ -22,9 +22,13 @@ const StoreSelectorPageQuery = graphql( [StoreLogoFragment], ); -export const metadata = { - title: 'Location selector', -}; +export async function generateMetadata() { + const t = await getTranslations('StoreSelector'); + + return { + title: t('title'), + }; +} interface Props { params: { locale: LocaleType }; diff --git a/core/messages/en.json b/core/messages/en.json index a380dffff..ab519c600 100644 --- a/core/messages/en.json +++ b/core/messages/en.json @@ -6,6 +6,7 @@ } }, "ChangePassword": { + "title": "Change password", "heading": "Change password", "Form": { "newPasswordLabel": "New password", @@ -21,6 +22,7 @@ } }, "Login": { + "title": "Login", "heading": "Log In", "Form": { "error": "Your email address or password is incorrect. Try signing in again or reset your password", @@ -44,6 +46,7 @@ } }, "Register": { + "title": "Register account", "heading": "New account", "Form": { "submit": "Create account", @@ -58,6 +61,7 @@ } }, "Reset": { + "title": "Reset password", "heading": "Reset password", "Form": { "description": "Enter the email associated with your account below. We'll send you instructions to reset your password.", @@ -121,6 +125,7 @@ "items": "items" }, "Search": { + "title": "Search results", "heading": "Search", "products": "Products", "sortBy": "{items, plural, =0 {no items} =1 {1 item} other {# items}}", @@ -140,12 +145,14 @@ "successMessage": "Your account has been successfully created" }, "Addresses": { + "title": "Addresses", "addNewAddress": "Add new address", "editButton": "Edit", "deleteButton": "Delete", "confirmDeleteAddress": "Delete address", "deleteModalTitle": "Are you sure you want to delete this address?", "Add": { + "title": "Add address", "heading": "New address", "Form": { "recaptchaText": "Pass ReCAPTCHA check", @@ -160,6 +167,7 @@ } }, "Edit": { + "title": "Edit address", "heading": "Edit address", "Form": { "recaptchaText": "Pass ReCAPTCHA check", @@ -183,6 +191,7 @@ } }, "Settings": { + "title": "Account settings", "emptyTextValidatoinMessage": "This field can not be empty", "cancel": "Cancel", "recaptchaText": "Pass ReCAPTCHA check", @@ -200,6 +209,7 @@ "phone": "Enter a phone number" }, "ChangePassword": { + "title": "Change password", "success": "Password has been updated successfully.", "error": "Unknown error.", "currentPasswordLabel": "Current password", @@ -222,6 +232,7 @@ } }, "Blog": { + "title": "Blog", "SharingLinks": { "share": "Share", "email": "Email", @@ -229,6 +240,7 @@ } }, "Cart": { + "title": "Cart", "heading": "Your cart", "empty": "Your cart is empty", "emptyDetails": "Looks like you have not added anything to your cart. Go ahead & explore top categories", @@ -299,6 +311,7 @@ } }, "Compare": { + "title": "Compare", "heading": "Comparing {quantity, plural, =1 {1 Product} other {# Products}}", "nothingToCompare": "Well, there's nothing to compare!", "helpingText": "You somehow managed to land here, but you need to select a few products first.", @@ -386,10 +399,12 @@ } }, "Maintenance": { + "title": "Maintenance", "message": "We are down for maintenance", "contactUs": "You can contact us at:" }, "StoreSelector": { + "title": "Store selector", "heading": "Select a language and region" }, "Error": {