feat: public API, SEO and existing surfaces
This commit is contained in:
1 parent
45fbbc33b1
commit
c390fcfe8d
103 files changed
+4476
-231
No files matched your search
@@ -0,0 +1,120 @@
|
||||
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.')
|
||||
}
|
||||
Reference in new issue
Block a user