feat(front): enhance localization support in AboutBaseInfo, useSeo, and default layout for improved SEO and user experience

This commit is contained in:
keven
2025-10-19 15:21:39 +08:00
parent 6238897c18
commit a4b3dad85e
4 changed files with 20 additions and 18 deletions

View File

@@ -8,6 +8,7 @@ import Progress from '~/components/ui/progress/Progress.vue'
import renderI18n from '~/lib/renderI18n'
import { I18nT } from 'vue-i18n'
const { locale } = useI18n()
const appConfig = useMyAppConfig()
const { data, isLoading } = useQuery({
queryKey: ['about'],
@@ -48,7 +49,7 @@ const genUserAvatar = (email: string) => {
<template v-else>
<NuxtImg v-if="data?.bg_url" :src="data?.bg_url" class="aspect-[3/1] w-full rounded-xl" fit="cover" />
<div class="flex flex-col gap-2 items-center">
<div class="text-xl">{{ renderI18n(appConfig?.site_title ?? {}, 'en') }}</div>
<div class="text-xl">{{ renderI18n(appConfig?.site_title ?? {}, 'en', locale) }}</div>
<div class="text-sm opacity-75 text-center px-5">
<I18nT keypath="about.powerBy" tag="span">
<NuxtLink href="https://github.com/keven1024/015" target="_blank" class="text-primary hover:underline">015</NuxtLink>

View File

@@ -1,14 +1,16 @@
import getApiBaseUrl from '~/lib/getApiBaseUrl'
import renderI18n from '~/lib/renderI18n'
type UseSeoProps = {
head?: Record<string, any>
seo?: Record<string, any>
locale?: string
}
const useSeo = async (props: UseSeoProps = {}) => {
const { head, seo } = props || {}
const { head, seo, locale } = props || {}
const seoMeta = ref<{
site_title: string
site_desc: string
site_title: Record<string, string>
site_desc: Record<string, string>
site_url: string
site_icon: string
site_bg_url: string
@@ -20,6 +22,8 @@ const useSeo = async (props: UseSeoProps = {}) => {
seoMeta.value = data
})
const { title } = head || {}
const siteTitle = computed(() => renderI18n(seoMeta?.value?.site_title || {}, 'en', locale))
const siteDesc = computed(() => renderI18n(seoMeta?.value?.site_desc || {}, 'en', locale))
useHead({
link: [
{ rel: 'icon', href: seoMeta.value?.site_icon || '/logo.png', sizes: 'any' },
@@ -31,14 +35,14 @@ const useSeo = async (props: UseSeoProps = {}) => {
{ name: 'theme-color', content: '#395276' },
],
...head,
title: title ? `${title} - ${seoMeta?.value?.site_title}` : seoMeta?.value?.site_title,
title: title ? `${title} - ${siteTitle.value}` : siteTitle.value,
})
useSeoMeta({
...seo,
title: seoMeta?.value?.site_title,
description: seoMeta?.value?.site_desc,
ogTitle: seoMeta?.value?.site_title,
ogDescription: seoMeta?.value?.site_desc,
title: siteTitle.value,
description: siteDesc.value,
ogTitle: siteTitle.value,
ogDescription: siteDesc.value,
ogImage: {
url: `${seoMeta?.value?.site_url}${seoMeta?.value?.site_icon || '/logo.png'}`,
width: 1024,

View File

@@ -1,16 +1,16 @@
<script lang="ts" setup>
import { Toaster } from 'vue-sonner'
await useSeo()
const { locale } = useI18n()
await useSeo({ locale: locale.value })
const appConfig = useMyAppConfig()
const bgUrl = computed(() => appConfig.value?.site_bg_url)
</script>
<template>
<div class="h-screen w-screen">
<GlobalDrawer />
<GlobalDayjs />
<Toaster position="top-center" richColors closeButton />
<img
class="w-full h-full object-cover absolute inset-0 -z-[1] bg-gradient-to-bl from-primary/40 to-primary"
src="https://img.fudaoyuan.icu/api/1/random/?scale_min=1.5&webp=true&md=false&format=302"
/>
<img class="w-full h-full object-cover absolute inset-0 -z-[1] bg-gradient-to-bl from-primary/40 to-primary" :src="bgUrl" />
<div class="h-full w-full flex flex-col items-center lg:p-10 p-5 overflow-y-auto">
<Navbar />
<slot />

View File

@@ -1,10 +1,7 @@
import { useI18n } from 'vue-i18n'
const renderI18n = (json: Record<string, string>, defaultKey: string, locale?: string) => {
const { locale: _locale } = useI18n()
if (!json) return ''
if (!locale) {
locale = _locale.value
return json?.[defaultKey]
}
if (!json?.[locale]) {
const [baseLocaleKey, subLocaleKey] = locale?.split('-') || []