The web-nuxt footer is manifest-driven. Edit apps/web-nuxt/zship.app.json and keep the footer content inside the top-level footer object.
Do not hardcode footer copy, links, or legal text in LandingFooter.vue. The component should only render siteConfig.footer.
Footer fields
{
"footer": {
"brandDisplay": "logo-and-site-name",
"contactEmail": "[email protected]",
"description": [
{
"en": "Short product promise for the footer.",
"zh-CN": "底部展示的简短产品说明。"
}
],
"socialLinks": [
{
"labelKey": "footer_github",
"to": "https://github.com/your-org/your-repo",
"external": true,
"icon": "i-simple-icons-github"
}
],
"sections": [
{
"titleKey": "footer_section_product",
"items": [
{
"labelKey": "nav_pricing",
"to": "/pricing"
}
]
}
],
"disclaimer": [
{
"en": "Optional legal or trademark disclaimer.",
"zh-CN": "可选的法律或商标免责声明。"
}
],
"copyright": "© {year} {siteName}"
}
}
Field reference
brandDisplay: controls brand rendering. Uselogo-and-site-name,logo-only, orsite-name-only.contactEmail: footer-specific email. Set it to an empty string to hide the email row. If the key is omitted, the app falls back to the top-levelcontactEmail.description: one or more footer description lines. Use localized objects when the public site supports multiple locales.socialLinks: icon buttons shown under the contact email. Each item needsto,icon, and eitherlabelKeyor localizedlabel. Use an empty array to hide all social buttons.sections: navigation columns. Each section usestitleKeyorlabel, and each item useslabelKeyorlabelplusto.disclaimer: legal or trademark text shown in the bottom row. Use an empty array to hide it.copyright: bottom-left copyright text. It supports{year},{siteName}, and{brandName}tokens. Set it to an empty string to hide it.
Labels and localization
Use labelKey when a label already exists in apps/web-nuxt/app/i18n/ui.json:
{
"labelKey": "footer_support",
"to": "/docs/support-and-refund"
}
Use localized label when the link is app-specific:
{
"label": {
"en": "Changelog",
"zh-CN": "更新日志"
},
"to": "/blog/changelog"
}
Localized text objects can include en, zh-CN, zh-TW, or default. If the active locale is missing, the resolver falls back to the default locale or the first non-empty value.
Link rules
- Internal routes should start with
/, for example/pricingor/docs/quick-start. - Hash links can use
/#section-id. - External links should set
"external": true. - Internal non-page assets such as
/llms.txtcan set"localize": falseto keep the exact URL. mailto:links are allowed, but footer email is usually clearer throughfooter.contactEmail.
Launch checklist
Before publishing the site:
- Confirm
footer.descriptionno longer references the template if the product has been renamed. - Confirm
footer.contactEmailreaches a real support mailbox. - Confirm every
footer.sections[].items[].toroute exists. - Confirm external links open the expected brand accounts.
- Confirm
footer.disclaimermatches your legal and trademark policy. - Run
pnpm --filter @zship/web-nuxt exec nuxt prepare.
