fix: escape @ in i18n messages, set useScope:'global' everywhere
Vue-i18n treats a bare '@' as the start of a linked-message reference,
which made every placeholder containing one — you{'@'}example.com,
the Telegram '{'@'}yourname' hint, the bad-Telegram error — crash the
compiler with "Invalid linked format". Escaping each '@' as the
literal {'@'} in en/es/fr fixes the compile and renders as a plain
'@' to the visitor.
Separately, every useI18n() call now passes { useScope: 'global' }.
Without it, components mounted inside <Form> / <Field> contexts
couldn't find a parent i18n scope and vue-i18n logged "Not found
parent scope. use the global scope." on every render. Explicit
global scope silences the warning and matches what the app
actually intends — there are no per-component message bundles.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
00e77ecf05
commit
c65ee029dd
14 changed files with 23 additions and 23 deletions
|
|
@ -25,7 +25,7 @@ import {
|
|||
} from '@/components/ui/select'
|
||||
import { submitInquiry, type ContactMethod } from '@/features/nostr/submitInquiry'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
|
||||
const METHODS: ContactMethod[] = ['email', 'whatsapp', 'signal', 'telegram', 'nostr']
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { Lock } from '@lucide/vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {
|
|||
} from '@/components/ui/dropdown-menu'
|
||||
import { SUPPORTED_LOCALES, persistLocale, type LocaleCode } from '@/i18n'
|
||||
|
||||
const { locale } = useI18n()
|
||||
const { locale } = useI18n({ useScope: 'global' })
|
||||
|
||||
function set(code: LocaleCode) {
|
||||
locale.value = code
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { RouterLink } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const year = new Date().getFullYear()
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import {
|
|||
import ThemeToggle from './ThemeToggle.vue'
|
||||
import LocaleSwitcher from './LocaleSwitcher.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
|
||||
const navItems = computed(() => [
|
||||
{ to: '/portfolio', label: t('nav.portfolio') },
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { useI18n } from 'vue-i18n'
|
|||
import { Moon, Sun } from '@lucide/vue'
|
||||
import { useTheme } from '@/composables/useTheme'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const { theme, toggle } = useTheme()
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import ProjectImage from './ProjectImage.vue'
|
|||
import type { Project } from '@/data/projects'
|
||||
|
||||
const props = defineProps<{ project: Project }>()
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
|
||||
const hero = computed(() => props.project.images.find((img) => img.feature === 'hero'))
|
||||
const rest = computed(() => props.project.images.filter((img) => img.feature !== 'hero'))
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog'
|
|||
import type { ProjectImage } from '@/data/projects'
|
||||
|
||||
const props = defineProps<{ image: ProjectImage }>()
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const open = ref(false)
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@
|
|||
"messageTooLong": "Keep it under 2000 characters.",
|
||||
"badEmail": "That does not look like an email address.",
|
||||
"badPhoneOrHandle": "Use a phone number or a handle.",
|
||||
"badTelegram": "Use a Telegram handle, like @yourname.",
|
||||
"badTelegram": "Use a Telegram handle, like {'@'}yourname.",
|
||||
"badNpub": "That does not look like an npub."
|
||||
},
|
||||
"toast": {
|
||||
|
|
@ -125,10 +125,10 @@
|
|||
"nostr": "Nostr"
|
||||
},
|
||||
"methodPlaceholders": {
|
||||
"email": "you@example.com",
|
||||
"email": "you{'@'}example.com",
|
||||
"whatsapp": "+1 555 123 4567",
|
||||
"signal": "+1 555 123 4567 or @username",
|
||||
"telegram": "@yourhandle",
|
||||
"signal": "+1 555 123 4567 or {'@'}username",
|
||||
"telegram": "{'@'}yourhandle",
|
||||
"nostr": "npub1…"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@
|
|||
"messageTooLong": "Manténgalo bajo 2000 caracteres.",
|
||||
"badEmail": "Eso no parece una dirección de correo.",
|
||||
"badPhoneOrHandle": "Use un número de teléfono o un usuario.",
|
||||
"badTelegram": "Use un usuario de Telegram, como @sunombre.",
|
||||
"badTelegram": "Use un usuario de Telegram, como {'@'}sunombre.",
|
||||
"badNpub": "Eso no parece un npub."
|
||||
},
|
||||
"toast": {
|
||||
|
|
@ -125,10 +125,10 @@
|
|||
"nostr": "Nostr"
|
||||
},
|
||||
"methodPlaceholders": {
|
||||
"email": "tu@ejemplo.com",
|
||||
"email": "tu{'@'}ejemplo.com",
|
||||
"whatsapp": "+34 600 123 456",
|
||||
"signal": "+34 600 123 456 o @usuario",
|
||||
"telegram": "@suusuario",
|
||||
"signal": "+34 600 123 456 o {'@'}usuario",
|
||||
"telegram": "{'@'}suusuario",
|
||||
"nostr": "npub1…"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@
|
|||
"messageTooLong": "Moins de 2000 caractères, s'il vous plaît.",
|
||||
"badEmail": "Cela ne ressemble pas à une adresse email.",
|
||||
"badPhoneOrHandle": "Utilisez un numéro de téléphone ou un pseudo.",
|
||||
"badTelegram": "Utilisez un pseudo Telegram, comme @votrenom.",
|
||||
"badTelegram": "Utilisez un pseudo Telegram, comme {'@'}votrenom.",
|
||||
"badNpub": "Cela ne ressemble pas à un npub."
|
||||
},
|
||||
"toast": {
|
||||
|
|
@ -125,10 +125,10 @@
|
|||
"nostr": "Nostr"
|
||||
},
|
||||
"methodPlaceholders": {
|
||||
"email": "vous@exemple.com",
|
||||
"email": "vous{'@'}exemple.com",
|
||||
"whatsapp": "+33 6 12 34 56 78",
|
||||
"signal": "+33 6 12 34 56 78 ou @pseudo",
|
||||
"telegram": "@votrepseudo",
|
||||
"signal": "+33 6 12 34 56 78 ou {'@'}pseudo",
|
||||
"telegram": "{'@'}votrepseudo",
|
||||
"nostr": "npub1…"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { useI18n } from 'vue-i18n'
|
|||
import ContactForm from '@/components/contact/ContactForm.vue'
|
||||
import PrivacyBlurb from '@/components/contact/PrivacyBlurb.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { AspectRatio } from '@/components/ui/aspect-ratio'
|
|||
import { Button } from '@/components/ui/button'
|
||||
import { projects } from '@/data/projects'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
|
||||
const projectCards = computed(() =>
|
||||
projects.map((p) => ({
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { useI18n } from 'vue-i18n'
|
|||
import { AspectRatio } from '@/components/ui/aspect-ratio'
|
||||
import { projects } from '@/data/projects'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
|
||||
const projectCards = computed(() =>
|
||||
projects.map((p) => ({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue