Back to docs

Footer configuration

Configure footer brand copy, contact email, social links, navigation columns, legal text, and copyright from zship.app.json.

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": {
    "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. Use logo-and-site-name, logo-only, or site-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-level contactEmail.
  • 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 needs to, icon, and either labelKey or localized label. Use an empty array to hide all social buttons.
  • sections: navigation columns. Each section uses titleKey or label, and each item uses labelKey or label plus to.
  • 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.

  • Internal routes should start with /, for example /pricing or /docs/quick-start.
  • Hash links can use /#section-id.
  • External links should set "external": true.
  • Internal non-page assets such as /llms.txt can set "localize": false to keep the exact URL.
  • mailto: links are allowed, but footer email is usually clearer through footer.contactEmail.

Launch checklist

Before publishing the site:

  • Confirm footer.description no longer references the template if the product has been renamed.
  • Confirm footer.contactEmail reaches a real support mailbox.
  • Confirm every footer.sections[].items[].to route exists.
  • Confirm external links open the expected brand accounts.
  • Confirm footer.disclaimer matches your legal and trademark policy.
  • Run pnpm --filter @zship/web-nuxt exec nuxt prepare.