Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions i18n/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@
"linkedin": "LinkedIn",
"github": "GitHub"
},
"nuxtSiteConfig": {
"description": "OneLiteFeather ist ein deutschsprachiges Minecraft-Netzwerk seit 2019 – mit Community-Bauten, Events und Open-Source-Software für Paper und Minestom."
},
"seo": {
"default_description": "OneLiteFeather ist ein deutschsprachiges Minecraft-Netzwerk seit 2019 – mit Community-Bauten, Events und Open-Source-Software für Paper und Minestom.",
"default_keywords": "OneLiteFeather, Minecraft, Minecraft Server, Minecraft Netzwerk, Plugins, Open Source, Paper, Velocity, Java, Bedrock, Entwicklungstools, Community"
Expand Down
3 changes: 3 additions & 0 deletions i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@
"linkedin": "LinkedIn",
"github": "GitHub"
},
"nuxtSiteConfig": {
"description": "OneLiteFeather is a German-speaking Minecraft network founded in 2019, with community builds, events and open-source software for Paper and Minestom."
},
"seo": {
"default_description": "OneLiteFeather is a German-speaking Minecraft network founded in 2019, with community builds, events and open-source software for Paper and Minestom.",
"default_keywords": "OneLiteFeather, Minecraft, Minecraft server, Minecraft network, plugins, open source, Paper, Velocity, Java, Bedrock, development tools, community"
Expand Down
4 changes: 1 addition & 3 deletions layers/content-core/composables/usePageSeo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ export function usePageSeo(opts: PageSeoOptions = {}) {

const pageTitle = computed(() => opts.title || site.name)
const pageDescription = computed(() => {
if (opts.description) return opts.description
if (site.description) return site.description
return t('seo.default_description')
return opts.description || t('seo.default_description') || site.description
})

// Resolve og:locale from the current locale code
Expand Down
1 change: 1 addition & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export default defineNuxtConfig({
]
})
},
// Localised description: i18n key `nuxtSiteConfig.description` (WebSite, og defaults).
site: {
url: 'http://localhost:3000',
name: 'OneLiteFeather Network',
Expand Down
70 changes: 70 additions & 0 deletions tests/seo/default-description.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// @vitest-environment nuxt
import { readFileSync } from 'node:fs'
import { mockNuxtImport, mountSuspended } from '@nuxt/test-utils/runtime'
import { flushPromises } from '@vue/test-utils'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { defineComponent, h, unref } from 'vue'
import { usePageSeo } from '../../layers/content-core/composables/usePageSeo'
import { repoRoot } from '../helpers/sources'

interface LocaleFile {
seo: { default_description: string }
nuxtSiteConfig?: { description?: string }
}

const messages = (code: string): LocaleFile => JSON.parse(readFileSync(`${repoRoot}/i18n/locales/${code}.json`, 'utf8'))

const DE_DEFAULT = messages('de').seo.default_description

// The static English site description that nuxt.config.ts declares. Tests
// override it to prove the page default does not come from it.
let siteDescriptionOverride: string | undefined
let seoMeta: Record<string, unknown> = {}

mockNuxtImport('useSiteConfig', (original) => () => {
const site = original()
if (siteDescriptionOverride === undefined) return site
return new Proxy(site, {
get: (target, key) => (key === 'description' ? siteDescriptionOverride : Reflect.get(target, key))
})
})

mockNuxtImport('useSeoMeta', (original) => (input: Record<string, unknown>) => {
seoMeta = input
return original(input as Parameters<typeof original>[0])
})

const probe = defineComponent({
setup() {
usePageSeo({ title: 'Imprint' })
return () => h('div')
}
})

const renderDescription = async (route: string): Promise<string> => {
await mountSuspended(probe, { route })
await flushPromises()
return String(unref(seoMeta.description))
}

beforeEach(() => {
siteDescriptionOverride = undefined
seoMeta = {}
// Nuxt OG image's compiler macro; the test environment has no transform for it.
vi.stubGlobal('defineOgImage', () => undefined)
})

describe('default page description', () => {
it('is the German default for a German page without its own description', async () => {
expect(await renderDescription('/de/imprint')).toBe(DE_DEFAULT)
})

it('prefers the localised default over the static site description', async () => {
siteDescriptionOverride = 'Static English site description'
expect(await renderDescription('/de/imprint')).toBe(DE_DEFAULT)
})

it('gives WebSite the German description on German pages', () => {
expect(messages('de').nuxtSiteConfig?.description).toBe(DE_DEFAULT)
})
})
Loading