Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 1x 3x 3x 3x 3x 3x 3x 3x 1x 3x | import type { Metadata } from 'next';
import { getLocaleMessages } from '@/lib/locale/locale';
import type { AuthMessages } from '../../types/common';
/**
* Helper to build SEO metadata for any page using localized messages.
*
* @param locale - locale string read from the cookie
* @param namespace - the key in the messages object (e.g. 'seo', 'auth', 'user')
* @param opts - keys to look up and fallback values
*/
export const getMetadata = async (
locale: string,
namespace: string,
opts: {
titleKey: string;
descriptionKey: string;
fallbackTitle: string;
fallbackDescription: string;
titleTemplate?: string; // Optional template like "%s | Cookbook"
keywordsKey?: string;
fallbackKeywords?: string;
robots?: {
index?: boolean;
follow?: boolean;
};
openGraph?: {
type?: 'website' | 'article';
};
},
): Promise<Metadata> => {
const messages = await getLocaleMessages(locale);
const data = (messages[namespace] ?? {}) as Record<string, string>;
const title =
typeof data[opts.titleKey] === 'string'
? data[opts.titleKey]
: opts.fallbackTitle;
const description =
typeof data[opts.descriptionKey] === 'string'
? data[opts.descriptionKey]
: opts.fallbackDescription;
const finalTitle = opts.titleTemplate
? opts.titleTemplate.replace('%s', title)
: `${title} | Cookbook`;
const keywords =
opts.keywordsKey && typeof data[opts.keywordsKey] === 'string'
? data[opts.keywordsKey]
: opts.fallbackKeywords;
return {
title: finalTitle,
description,
...(keywords === undefined ? {} : { keywords }),
...(opts.robots === undefined ? {} : { robots: opts.robots }),
openGraph: {
title: finalTitle,
description,
type: opts.openGraph?.type ?? 'website',
},
twitter: {
card: 'summary',
title: finalTitle,
description,
},
};
};
/**
* Helper to build SEO metadata for auth‑related pages.
*
* @param locale - locale string read from the cookie
* @param opts - keys to look up in the `auth` namespace and fallback values
*/
export const getAuthMetadata = async (
locale: string,
opts: {
titleKey: keyof AuthMessages;
descriptionKey: keyof AuthMessages;
fallbackTitle: string;
fallbackDescription: string;
},
): Promise<Metadata> => {
return getMetadata(locale, 'auth', {
...opts,
titleKey: String(opts.titleKey),
descriptionKey: String(opts.descriptionKey),
});
};
|