Getting Started

Customization

Where to change your project's colors, logo, name, fonts, and page head.

Your project has two applications and a set of layers they share. Before you change anything, decide which one owns it:

  • apps/site is the public website: marketing pages, blog, docs, legal pages, contact form.
  • apps/web is the signed-in product: account settings, administration, billing, APIs.
  • packages/layer-* holds anything both applications use, or anything you'd want to copy into another Nuxt project.

Change a value in the application when it belongs to that application alone. Change it in a layer when both applications should follow. Technical details covers the ownership rule in full.

Colors

Nuxt UI reads its semantic colors from an application's app/app.config.ts. Neither application ships one, so create the file in whichever application you want to change:

apps/site/app/app.config.ts
export default defineAppConfig({
  ui: {
    colors: {
      primary: 'sky',
      secondary: 'indigo',
      neutral: 'slate',
    },
  },
})

packages/layer-base/app/app.config.ts already sets shared UI defaults, and the file you just created merges over them — write only the keys you want to differ. The Nuxt UI design system lists every color and token you can set.

The brand color is separate

Two things render outside the browser and can't read Nuxt UI's theme: the fallback social image and the buttons in transactional email. Both read one constant:

packages/layer-base/shared/utils/constants.ts
export const BRAND_COLOR = '#00DC82'

Change it alongside your Nuxt UI colors, or your emails and social images drift away from your interface.

Name

Your product name lives in .env.project.schema at the root of the repository, because it names the product and not the deployment — and because both applications read the same one:

.env.project.schema
PROJECT_DISPLAY_NAME=Acme

It reaches page titles, transactional email, and social images, arriving in each application as NUXT_PUBLIC_APP_NAME.

It ships as REPLACE_ME, and nothing rejects that at build time. The deploy gate is what holds it, and because it's read by both applications it holds every Runtime Context of both back rather than one — so a deploy ships nothing until you have set it.

Project identity covers the rest of that file, and every name derived from it.

URLs and indexing

Each of these describes a deployment rather than the product, so they live in the value files rather than the schema:

KeySet inWhat it does
NUXT_PUBLIC_APP_BASE_URLBoth applicationsThe origin that application is served from
NUXT_PUBLIC_APP_WEBSITE_BASE_URLapps/web onlyPoints the product at the public website
NUXT_PUBLIC_SITE_INDEXABLEBoth applicationsWhether search engines may index it

Environment values explains which file each one belongs in. First deploy is where you write the non-production origins, and Going to production is where you write production's.

Each application serves its own logo from its public/ directory:

apps/site/public/logo.png
apps/web/public/logo.png

Replacing those two files is the whole change. packages/layer-base defaults app.logo to /logo.png, and the shared AppLogo component renders it.

To use a different file per color mode, set app.logo to an object instead, in that application's app/app.config.ts — creating the file if you have not already:

apps/web/app/app.config.ts
export default defineAppConfig({
  app: {
    logo: {
      light: '/logo-light.svg',
      dark: '/logo-dark.svg',
    },
  },
})

AppLogo accepts either shape — a string renders one image, an object renders a color-mode pair — so nothing else has to change. Put the files in that application's public/ directory.

Deploying both applications? The website can host the shared assets, and apps/web can point app.logo at an absolute URL on it instead of keeping a second copy.

Favicon and page head

Replace apps/site/public/favicon.ico and apps/web/public/favicon.ico. Nuxt serves them without any configuration, so there's nothing to declare unless you want a different filename or format.

The app.head block in an application's config is where the rest of the static head lives:

apps/site/nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      title: ENV.NUXT_PUBLIC_APP_NAME,
      htmlAttrs: {
        lang: 'en',
      },
    },
  },
})

Nuxt's SEO and meta guide covers the full API.

Fonts and design tokens

Each application owns a CSS entry point at app/assets/css/main.css, which imports a tailwind.css beside it. Tailwind v4 theme tokens go in the second file:

apps/site/app/assets/css/tailwind.css
@theme {
  --font-sans: 'Inter', sans-serif;
  --font-mono: 'JetBrains Mono', monospace;
}

The token defines the utility. Loading the font is a separate step — the browser needs the file before the utility means anything. Tailwind's theme documentation covers the other token groups.

Website settings

Values that belong to the public website, rather than to either application, live in the site layer's app config. The social links are there today:

packages/layer-site/app/app.config.ts
export default defineAppConfig({
  socials: {
    x: 'https://x.com/your-handle',
  },
})

The blog and docs layers each register their own content section from their own nuxt.config.ts, under appConfig.contentSections. A new content section of your own follows that pattern in its own layer.

Next steps

Copyright © 2026