SEO: multilingual homepage (homeSlug per locale in path/sitemap), Article + llms.txt generators, siteDescription fallback, composeTitle dedup
This commit is contained in:
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
import type { BasePayload } from 'payload';
|
||||
import type { I18nConfig } from '../i18n/index.js';
|
||||
type BuildLlmsTxtArgs = {
|
||||
/** Absolute site URL (https://…). */
|
||||
baseUrl: string;
|
||||
config: I18nConfig;
|
||||
/** Locale for names/descriptions. Defaults to config.defaultLocale. */
|
||||
locale?: string;
|
||||
/** Pages collection slug. Defaults to 'pages'. */
|
||||
pagesSlug?: string;
|
||||
payload: BasePayload;
|
||||
/** Site settings global slug. Defaults to 'site-settings'. */
|
||||
settingsSlug?: string;
|
||||
};
|
||||
/**
|
||||
* Builds the body of /llms.txt — a Markdown file describing the site for AI
|
||||
* agents / LLM crawlers, per the llmstxt.org convention. Mirrors buildRobots /
|
||||
* buildSitemapEntries: the plugin already knows the site's name, description,
|
||||
* and pages, so it can generate this automatically.
|
||||
*
|
||||
* Structure (llmstxt.org): H1 site name, a blockquote/summary, then a list of
|
||||
* key pages as Markdown links with short descriptions. Agents read this to
|
||||
* understand the site quickly without crawling everything.
|
||||
*
|
||||
* Wire it as a route that returns text/plain:
|
||||
*
|
||||
* // app/llms.txt/route.ts
|
||||
* import { buildLlmsTxt } from '@intecion/ipal-kit'
|
||||
* import { getCachedPayload } from '@/lib/content'
|
||||
* import { i18nConfig } from '@/i18n.config'
|
||||
* export const dynamic = 'force-dynamic'
|
||||
* export async function GET() {
|
||||
* const body = await buildLlmsTxt({
|
||||
* payload: await getCachedPayload(),
|
||||
* config: i18nConfig,
|
||||
* baseUrl: process.env.NEXT_PUBLIC_SERVER_URL!,
|
||||
* })
|
||||
* return new Response(body, { headers: { 'Content-Type': 'text/plain; charset=utf-8' } })
|
||||
* }
|
||||
*
|
||||
* Data comes from the panel (siteName, siteDescription, pages) — nothing
|
||||
* hardcoded. Skips drafts and noindex pages (same as the sitemap).
|
||||
*/
|
||||
export declare function buildLlmsTxt({ baseUrl, config, locale, pagesSlug, payload, settingsSlug, }: BuildLlmsTxtArgs): Promise<string>;
|
||||
export {};
|
||||
Vendored
+90
@@ -0,0 +1,90 @@
|
||||
import { buildLocalizedPath } from '../i18n/index.js';
|
||||
/**
|
||||
* Builds the body of /llms.txt — a Markdown file describing the site for AI
|
||||
* agents / LLM crawlers, per the llmstxt.org convention. Mirrors buildRobots /
|
||||
* buildSitemapEntries: the plugin already knows the site's name, description,
|
||||
* and pages, so it can generate this automatically.
|
||||
*
|
||||
* Structure (llmstxt.org): H1 site name, a blockquote/summary, then a list of
|
||||
* key pages as Markdown links with short descriptions. Agents read this to
|
||||
* understand the site quickly without crawling everything.
|
||||
*
|
||||
* Wire it as a route that returns text/plain:
|
||||
*
|
||||
* // app/llms.txt/route.ts
|
||||
* import { buildLlmsTxt } from '@intecion/ipal-kit'
|
||||
* import { getCachedPayload } from '@/lib/content'
|
||||
* import { i18nConfig } from '@/i18n.config'
|
||||
* export const dynamic = 'force-dynamic'
|
||||
* export async function GET() {
|
||||
* const body = await buildLlmsTxt({
|
||||
* payload: await getCachedPayload(),
|
||||
* config: i18nConfig,
|
||||
* baseUrl: process.env.NEXT_PUBLIC_SERVER_URL!,
|
||||
* })
|
||||
* return new Response(body, { headers: { 'Content-Type': 'text/plain; charset=utf-8' } })
|
||||
* }
|
||||
*
|
||||
* Data comes from the panel (siteName, siteDescription, pages) — nothing
|
||||
* hardcoded. Skips drafts and noindex pages (same as the sitemap).
|
||||
*/ export async function buildLlmsTxt({ baseUrl, config, locale, pagesSlug = 'pages', payload, settingsSlug = 'site-settings' }) {
|
||||
const loc = locale ?? config.defaultLocale;
|
||||
const origin = baseUrl.replace(/\/$/, '');
|
||||
const settings = await payload.findGlobal({
|
||||
slug: settingsSlug,
|
||||
depth: 0,
|
||||
locale: loc
|
||||
});
|
||||
const name = settings.siteName?.trim() || 'Website';
|
||||
const description = settings.siteDescription?.trim();
|
||||
const result = await payload.find({
|
||||
collection: pagesSlug,
|
||||
depth: 0,
|
||||
limit: 1000,
|
||||
locale: loc,
|
||||
where: {
|
||||
_status: {
|
||||
not_equals: 'draft'
|
||||
}
|
||||
}
|
||||
});
|
||||
const lines = [
|
||||
`# ${name}`,
|
||||
''
|
||||
];
|
||||
if (description) {
|
||||
lines.push(`> ${description}`, '');
|
||||
}
|
||||
const pageLinks = [];
|
||||
for (const raw of result.docs){
|
||||
if (raw._status && raw._status !== 'published') {
|
||||
continue;
|
||||
}
|
||||
if (raw.meta?.noindex) {
|
||||
continue;
|
||||
}
|
||||
const title = typeof raw.title === 'string' ? raw.title : undefined;
|
||||
const slug = typeof raw.slug === 'string' ? raw.slug : undefined;
|
||||
if (!title || !slug) {
|
||||
continue;
|
||||
}
|
||||
const path = buildLocalizedPath({
|
||||
config,
|
||||
locale: loc,
|
||||
slugs: {
|
||||
[loc]: slug
|
||||
}
|
||||
});
|
||||
if (!path) {
|
||||
continue;
|
||||
}
|
||||
const pageDesc = typeof raw.meta?.description === 'string' ? ` — ${raw.meta.description}` : '';
|
||||
pageLinks.push(`- [${title}](${origin}${path})${pageDesc}`);
|
||||
}
|
||||
if (pageLinks.length > 0) {
|
||||
lines.push('## Strony', '', ...pageLinks, '');
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
//# sourceMappingURL=buildLlmsTxt.js.map
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+8
-2
@@ -31,7 +31,7 @@ type BuildMetadataArgs = {
|
||||
baseUrl?: string;
|
||||
config: I18nConfig;
|
||||
/** Home slug that collapses to the locale root. Defaults to 'home'. */
|
||||
homeSlug?: string | Record<string, string>;
|
||||
homeSlug?: Record<string, string> | string;
|
||||
/** Resolved OG image URL (page image or site defaultShareImage). */
|
||||
imageUrl?: null | string;
|
||||
/** Current locale being rendered. */
|
||||
@@ -63,6 +63,12 @@ type BuildMetadataArgs = {
|
||||
query?: string;
|
||||
/** Separator between page title and site name. Defaults to ' | '. */
|
||||
separator?: string;
|
||||
/**
|
||||
* Global fallback description (from SiteSettings.siteDescription). Used when a
|
||||
* page has no meta.description — better than emitting no description at all
|
||||
* (Google would then scrape random on-page text for the snippet).
|
||||
*/
|
||||
siteDescription?: null | string;
|
||||
/** Site name for title composition and OG. */
|
||||
siteName?: null | string;
|
||||
/** slug per locale for this document — drives canonical + hreflang. */
|
||||
@@ -77,5 +83,5 @@ type BuildMetadataArgs = {
|
||||
* pieces (meta group, site name, image URL, localized slugs) and passes them
|
||||
* in — the plugin composes, it doesn't fetch.
|
||||
*/
|
||||
export declare function buildMetadata({ baseUrl, config, homeSlug, imageUrl, locale, meta, order, pageTitle, prefix, query, separator, siteName, slugs, }: BuildMetadataArgs): PageMetadata;
|
||||
export declare function buildMetadata({ baseUrl, config, homeSlug, imageUrl, locale, meta, order, pageTitle, prefix, query, separator, siteDescription, siteName, slugs, }: BuildMetadataArgs): PageMetadata;
|
||||
export {};
|
||||
|
||||
Vendored
+2
-2
@@ -9,7 +9,7 @@ import { buildHreflangAlternates } from './hreflang.js';
|
||||
* Designed for use inside Next.js `generateMetadata`. The caller resolves the
|
||||
* pieces (meta group, site name, image URL, localized slugs) and passes them
|
||||
* in — the plugin composes, it doesn't fetch.
|
||||
*/ export function buildMetadata({ baseUrl, config, homeSlug = 'home', imageUrl, locale, meta, order, pageTitle, prefix, query, separator, siteName, slugs }) {
|
||||
*/ export function buildMetadata({ baseUrl, config, homeSlug = 'home', imageUrl, locale, meta, order, pageTitle, prefix, query, separator, siteDescription, siteName, slugs }) {
|
||||
// Title source priority: titleOverride (exact, wins outright) > meta.title
|
||||
// (SEO title an editor set) > pageTitle (the document's own name). This means
|
||||
// a page with no SEO title still shows its name (e.g. 'Sprzątanie biur')
|
||||
@@ -22,7 +22,7 @@ import { buildHreflangAlternates } from './hreflang.js';
|
||||
separator,
|
||||
siteName
|
||||
});
|
||||
const description = meta?.description?.trim() || undefined;
|
||||
const description = meta?.description?.trim() || siteDescription?.trim() || undefined;
|
||||
const origin = baseUrl?.replace(/\/$/, '') ?? '';
|
||||
const suffix = query ?? '';
|
||||
const currentPath = buildLocalizedPath({
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
@@ -4,6 +4,7 @@ export { buildArticleJsonLd } from './buildArticleJsonLd.js';
|
||||
export { buildBreadcrumbJsonLd } from './buildBreadcrumbJsonLd.js';
|
||||
export { buildFaqJsonLd } from './buildFaqJsonLd.js';
|
||||
export { buildIconsMetadata } from './buildIconsMetadata.js';
|
||||
export { buildLlmsTxt } from './buildLlmsTxt.js';
|
||||
export { buildLocalBusinessJsonLd } from './buildLocalBusinessJsonLd.js';
|
||||
export { buildMetadata } from './buildMetadata.js';
|
||||
export type { PageMetadata } from './buildMetadata.js';
|
||||
|
||||
Vendored
+1
@@ -3,6 +3,7 @@ export { buildArticleJsonLd } from './buildArticleJsonLd.js';
|
||||
export { buildBreadcrumbJsonLd } from './buildBreadcrumbJsonLd.js';
|
||||
export { buildFaqJsonLd } from './buildFaqJsonLd.js';
|
||||
export { buildIconsMetadata } from './buildIconsMetadata.js';
|
||||
export { buildLlmsTxt } from './buildLlmsTxt.js';
|
||||
export { buildLocalBusinessJsonLd } from './buildLocalBusinessJsonLd.js';
|
||||
export { buildMetadata } from './buildMetadata.js';
|
||||
export { buildOrganizationJsonLd } from './buildOrganizationJsonLd.js';
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"sources":["../../../src/modules/seo/index.ts"],"sourcesContent":["export { buildAutoFillMetaHook } from './autoFillMeta.js'\nexport type { AutoFillMapping } from './autoFillMeta.js'\nexport { buildArticleJsonLd } from './buildArticleJsonLd.js'\nexport { buildBreadcrumbJsonLd } from './buildBreadcrumbJsonLd.js'\nexport { buildFaqJsonLd } from './buildFaqJsonLd.js'\nexport { buildIconsMetadata } from './buildIconsMetadata.js'\nexport { buildLocalBusinessJsonLd } from './buildLocalBusinessJsonLd.js'\nexport { buildMetadata } from './buildMetadata.js'\nexport type { PageMetadata } from './buildMetadata.js'\nexport { buildOrganizationJsonLd } from './buildOrganizationJsonLd.js'\nexport { buildRobots } from './buildRobots.js'\nexport type { RobotsRules } from './buildRobots.js'\nexport { buildServiceJsonLd } from './buildServiceJsonLd.js'\nexport { buildSitemapEntries } from './buildSitemapEntries.js'\nexport type { SitemapEntry } from './buildSitemapEntries.js'\nexport { buildSiteNavigationJsonLd } from './buildSiteNavigationJsonLd.js'\nexport { buildWebSiteJsonLd } from './buildWebSiteJsonLd.js'\nexport { composeTitle } from './composeTitle.js'\nexport type { TitleOrder } from './composeTitle.js'\nexport { createMetadataGenerator } from './createMetadataGenerator.js'\nexport { createPageMetadata } from './createPageMetadata.js'\nexport { buildHreflangAlternates } from './hreflang.js'\nexport { injectAutoFillMeta } from './injectAutoFillMeta.js'\nexport { injectSeoTabs } from './injectSeoTabs.js'\nexport { readSiteMetaConfig } from './readSiteMetaConfig.js'\nexport type { SiteMetaConfig } from './readSiteMetaConfig.js'\nexport { buildSeoPlugin } from './seoPluginConfig.js'\nexport { slugsAcrossLocales } from './slugsAcrossLocales.js'\nexport type { SeoMeta, SeoOption } from './types.js'\nexport { validateFaviconField } from './validateFavicon.js'\n"],"names":["buildAutoFillMetaHook","buildArticleJsonLd","buildBreadcrumbJsonLd","buildFaqJsonLd","buildIconsMetadata","buildLocalBusinessJsonLd","buildMetadata","buildOrganizationJsonLd","buildRobots","buildServiceJsonLd","buildSitemapEntries","buildSiteNavigationJsonLd","buildWebSiteJsonLd","composeTitle","createMetadataGenerator","createPageMetadata","buildHreflangAlternates","injectAutoFillMeta","injectSeoTabs","readSiteMetaConfig","buildSeoPlugin","slugsAcrossLocales","validateFaviconField"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,oBAAmB;AAEzD,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,qBAAqB,QAAQ,6BAA4B;AAClE,SAASC,cAAc,QAAQ,sBAAqB;AACpD,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,wBAAwB,QAAQ,gCAA+B;AACxE,SAASC,aAAa,QAAQ,qBAAoB;AAElD,SAASC,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,WAAW,QAAQ,mBAAkB;AAE9C,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,mBAAmB,QAAQ,2BAA0B;AAE9D,SAASC,yBAAyB,QAAQ,iCAAgC;AAC1E,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,YAAY,QAAQ,oBAAmB;AAEhD,SAASC,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,uBAAuB,QAAQ,gBAAe;AACvD,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,kBAAkB,QAAQ,0BAAyB;AAE5D,SAASC,cAAc,QAAQ,uBAAsB;AACrD,SAASC,kBAAkB,QAAQ,0BAAyB;AAE5D,SAASC,oBAAoB,QAAQ,uBAAsB"}
|
||||
{"version":3,"sources":["../../../src/modules/seo/index.ts"],"sourcesContent":["export { buildAutoFillMetaHook } from './autoFillMeta.js'\nexport type { AutoFillMapping } from './autoFillMeta.js'\nexport { buildArticleJsonLd } from './buildArticleJsonLd.js'\nexport { buildBreadcrumbJsonLd } from './buildBreadcrumbJsonLd.js'\nexport { buildFaqJsonLd } from './buildFaqJsonLd.js'\nexport { buildIconsMetadata } from './buildIconsMetadata.js'\nexport { buildLlmsTxt } from './buildLlmsTxt.js'\nexport { buildLocalBusinessJsonLd } from './buildLocalBusinessJsonLd.js'\nexport { buildMetadata } from './buildMetadata.js'\nexport type { PageMetadata } from './buildMetadata.js'\nexport { buildOrganizationJsonLd } from './buildOrganizationJsonLd.js'\nexport { buildRobots } from './buildRobots.js'\nexport type { RobotsRules } from './buildRobots.js'\nexport { buildServiceJsonLd } from './buildServiceJsonLd.js'\nexport { buildSitemapEntries } from './buildSitemapEntries.js'\nexport type { SitemapEntry } from './buildSitemapEntries.js'\nexport { buildSiteNavigationJsonLd } from './buildSiteNavigationJsonLd.js'\nexport { buildWebSiteJsonLd } from './buildWebSiteJsonLd.js'\nexport { composeTitle } from './composeTitle.js'\nexport type { TitleOrder } from './composeTitle.js'\nexport { createMetadataGenerator } from './createMetadataGenerator.js'\nexport { createPageMetadata } from './createPageMetadata.js'\nexport { buildHreflangAlternates } from './hreflang.js'\nexport { injectAutoFillMeta } from './injectAutoFillMeta.js'\nexport { injectSeoTabs } from './injectSeoTabs.js'\nexport { readSiteMetaConfig } from './readSiteMetaConfig.js'\nexport type { SiteMetaConfig } from './readSiteMetaConfig.js'\nexport { buildSeoPlugin } from './seoPluginConfig.js'\nexport { slugsAcrossLocales } from './slugsAcrossLocales.js'\nexport type { SeoMeta, SeoOption } from './types.js'\nexport { validateFaviconField } from './validateFavicon.js'\n"],"names":["buildAutoFillMetaHook","buildArticleJsonLd","buildBreadcrumbJsonLd","buildFaqJsonLd","buildIconsMetadata","buildLlmsTxt","buildLocalBusinessJsonLd","buildMetadata","buildOrganizationJsonLd","buildRobots","buildServiceJsonLd","buildSitemapEntries","buildSiteNavigationJsonLd","buildWebSiteJsonLd","composeTitle","createMetadataGenerator","createPageMetadata","buildHreflangAlternates","injectAutoFillMeta","injectSeoTabs","readSiteMetaConfig","buildSeoPlugin","slugsAcrossLocales","validateFaviconField"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,oBAAmB;AAEzD,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,qBAAqB,QAAQ,6BAA4B;AAClE,SAASC,cAAc,QAAQ,sBAAqB;AACpD,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,YAAY,QAAQ,oBAAmB;AAChD,SAASC,wBAAwB,QAAQ,gCAA+B;AACxE,SAASC,aAAa,QAAQ,qBAAoB;AAElD,SAASC,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,WAAW,QAAQ,mBAAkB;AAE9C,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,mBAAmB,QAAQ,2BAA0B;AAE9D,SAASC,yBAAyB,QAAQ,iCAAgC;AAC1E,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,YAAY,QAAQ,oBAAmB;AAEhD,SAASC,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,uBAAuB,QAAQ,gBAAe;AACvD,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,kBAAkB,QAAQ,0BAAyB;AAE5D,SAASC,cAAc,QAAQ,uBAAsB;AACrD,SAASC,kBAAkB,QAAQ,0BAAyB;AAE5D,SAASC,oBAAoB,QAAQ,uBAAsB"}
|
||||
+8
-6
@@ -1,10 +1,6 @@
|
||||
import type { BasePayload } from 'payload';
|
||||
import type { TitleOrder } from './composeTitle.js';
|
||||
export type SiteMetaConfig = {
|
||||
siteName: string | null;
|
||||
/** Padded separator, e.g. ' | ' — the panel stores the bare character. */
|
||||
separator?: string;
|
||||
order?: TitleOrder;
|
||||
/**
|
||||
* Home slug per locale, e.g. { pl: 'strona-glowna', de: 'startseite' }. A map
|
||||
* (not a single string) so multilingual homepages collapse to root in EVERY
|
||||
@@ -12,6 +8,12 @@ export type SiteMetaConfig = {
|
||||
* instead of '/de', breaking return tags (a real GSC error).
|
||||
*/
|
||||
homeSlug?: Record<string, string>;
|
||||
order?: TitleOrder;
|
||||
/** Padded separator, e.g. ' | ' — the panel stores the bare character. */
|
||||
separator?: string;
|
||||
/** Global fallback meta description. */
|
||||
siteDescription?: null | string;
|
||||
siteName: null | string;
|
||||
};
|
||||
/**
|
||||
* Reads the site-wide inputs to title and URL composition from SiteSettings.
|
||||
@@ -21,9 +23,9 @@ export type SiteMetaConfig = {
|
||||
* that the separator arrives unpadded, or that the home slug hides inside a
|
||||
* relationship — it should receive a resolved config.
|
||||
*/
|
||||
export declare function readSiteMetaConfig({ payload, locale, settingsSlug, siteNameField, }: {
|
||||
payload: BasePayload;
|
||||
export declare function readSiteMetaConfig({ locale, payload, settingsSlug, siteNameField, }: {
|
||||
locale: string;
|
||||
payload: BasePayload;
|
||||
settingsSlug?: string;
|
||||
siteNameField?: string;
|
||||
}): Promise<SiteMetaConfig>;
|
||||
|
||||
+15
-10
@@ -5,13 +5,13 @@
|
||||
* whatever an editor set in the panel. Metadata generation shouldn't also know
|
||||
* that the separator arrives unpadded, or that the home slug hides inside a
|
||||
* relationship — it should receive a resolved config.
|
||||
*/ export async function readSiteMetaConfig({ payload, locale, settingsSlug = 'site-settings', siteNameField = 'siteName' }) {
|
||||
*/ export async function readSiteMetaConfig({ locale, payload, settingsSlug = 'site-settings', siteNameField = 'siteName' }) {
|
||||
// depth 1 populates the homepage relationship, so its slug is available
|
||||
// without a second query.
|
||||
const settings = await payload.findGlobal({
|
||||
slug: settingsSlug,
|
||||
locale: locale,
|
||||
depth: 1
|
||||
depth: 1,
|
||||
locale: locale
|
||||
});
|
||||
const homepage = settings.homepage && typeof settings.homepage === 'object' ? settings.homepage : null;
|
||||
// Build the per-locale home slug map. The homepage's slug is localized, so a
|
||||
@@ -22,18 +22,22 @@
|
||||
if (homepage?.id) {
|
||||
try {
|
||||
const homeDoc = await payload.findByID({
|
||||
collection: 'pages',
|
||||
id: homepage.id,
|
||||
locale: 'all',
|
||||
depth: 0
|
||||
collection: 'pages',
|
||||
depth: 0,
|
||||
locale: 'all'
|
||||
});
|
||||
const slugField = homeDoc.slug;
|
||||
if (slugField && typeof slugField === 'object') {
|
||||
const map = {};
|
||||
for (const [loc, value] of Object.entries(slugField)){
|
||||
if (typeof value === 'string') map[loc] = value;
|
||||
if (typeof value === 'string') {
|
||||
map[loc] = value;
|
||||
}
|
||||
}
|
||||
if (Object.keys(map).length > 0) {
|
||||
homeSlug = map;
|
||||
}
|
||||
if (Object.keys(map).length > 0) homeSlug = map;
|
||||
} else if (typeof slugField === 'string') {
|
||||
// Non-localized slug (same in every language) — key it by current locale;
|
||||
// buildLocalizedPath tolerates a partial map. Non-localized homepage
|
||||
@@ -54,11 +58,12 @@
|
||||
};
|
||||
}
|
||||
return {
|
||||
siteDescription: settings.siteDescription ?? null,
|
||||
siteName: settings[siteNameField] ?? null,
|
||||
// The panel stores '|'; titles need it padded.
|
||||
separator: settings.titleSeparator ? ` ${settings.titleSeparator} ` : undefined,
|
||||
homeSlug,
|
||||
order: settings.titleOrder ?? undefined,
|
||||
homeSlug
|
||||
separator: settings.titleSeparator ? ` ${settings.titleSeparator} ` : undefined
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user