Files
RenewCMS/web/src/lib/localizedSeo.ts
T

121 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { locale, t } from '@/i18n'
import type { ResolvedSeo } from '@/lib/seoTypes'
import { languageName } from '@/lib/siteLanguages'
import { nameInSentence } from '@/lib/storyList'
export interface LocalizedSeoContext {
lang: string
siteName: string
siteKey: string
pattern: string | null
defaultLang: string
disabledLangs: string[]
published: boolean
socialState: string
resolved: ResolvedSeo | null
}
export function pageLanguage(context: LocalizedSeoContext) {
return languageName(context.lang, locale.value)
}
export function breadcrumbOf(url: string) {
try {
const parsed = new URL(url)
const segments = parsed.pathname.split('/').filter(Boolean)
return [parsed.host, ...segments].join(' › ')
} catch {
return url
}
}
export function canonicalNote(context: LocalizedSeoContext) {
if (context.resolved?.fallbacks.canonical === 'canonical_url') {
return t('Set by hand as a canonical override on this version.')
}
return t(
'Built from the Public URL pattern {0}. Each language points to itself unless you set a canonical override.',
[context.pattern ?? ''],
)
}
export function disabledNote(context: LocalizedSeoContext) {
if (context.disabledLangs.length === 0) {
return t('Drafts are left out.')
}
const names = context.disabledLangs.map((tag) => nameInSentence(tag))
const list = names.join(', ')
return names.length === 1
? t('Drafts and the disabled {0} language are left out.', [list])
: t('Drafts and the disabled languages {0} are left out.', [list])
}
export function socialLocaleLine(context: LocalizedSeoContext) {
const value = context.resolved?.og.locale ?? ''
if (!value) {
return t('Social locale not set')
}
return context.socialState === 'derived' ? t('Derived: {0}', [value]) : t('Set: {0}', [value])
}
export function socialLocaleNote(context: LocalizedSeoContext) {
const name = pageLanguage(context)
if (!context.resolved?.og.locale) {
return t(
'{0} has no region in its code and no social locale is set for it, so og:locale and og:locale:alternate are left out. An owner can set one in {1} languages.',
[name, context.siteName],
)
}
if (context.socialState === 'derived') {
return t(
'Taken from the region of the language code or of the site locale. An owner can set another in {0} languages.',
[context.siteName],
)
}
return t(
'Set by an owner for {0} in {1} languages. A region is never guessed from the language.',
[name, context.siteName],
)
}
export function titleHelp(context: LocalizedSeoContext) {
const source = context.resolved?.fallbacks.title
return source === 'title' ? t('Fallback: {0} title', [nameInSentence(context.lang)]) : ''
}
export function descriptionHelp(context: LocalizedSeoContext) {
const fallbacks = context.resolved?.fallbacks
if (!fallbacks) {
return ''
}
const name = nameInSentence(context.lang)
switch (fallbacks.description) {
case 'excerpt':
return t('Fallback: {0} excerpt', [name])
case 'body':
return t('Fallback: {0} body', [name])
case 'site':
return t('Fallback: {0} site description', [name])
case 'none':
return fallbacks.site_text_skipped
? t('No fallback. Empty. {0} site default not used. The tag is left out.', [
nameInSentence(context.defaultLang),
])
: t('No fallback')
default:
return ''
}
}
export function descriptionBadge(context: LocalizedSeoContext) {
const fallbacks = context.resolved?.fallbacks
if (fallbacks?.description === 'site') {
return t('Uses site text')
}
return fallbacks?.site_text_skipped ? t('Tag left out') : ''
}
export function altHelp() {
return t('Written per language.')
}