Getting Started
@nexub/brand ships the official Nexub files: the mark, the app icon tiles, PNG icons and the favicon. Use these instead of keeping your own copies. They come from the same master artwork as <Logo>; nothing is redrawn.
pnpm add @nexub/brand| File | Use it for |
|---|---|
nexub-mark.svg | The mark in brand colours. |
nexub-mark-mono.svg | Single-colour mark (fill="currentColor"). |
app-icon.svg | App icon: the black glass tile with the mark. SVG favicon, launcher tiles. |
app-icon-192.png, app-icon-512.png | Web manifest icons, apple-touch-icon. |
app-icon-account.svg, -192.png, -512.png | The Account tile: same tile, person glyph. |
favicon.ico | 16, 32 and 48 px favicon. |
Every file is at @nexub/brand/<file>. Inside React UI, prefer <Logo> and <NexubMark>: they render the same mark inline, with no extra request.
Why a separate package: the files are static and need no build, so an app that only wants a favicon doesn't install React, and the version still moves in lockstep with the other @nexub/* packages.
Importing a file gives you a hashed URL, and Vite copies the file into the build.
import hubIcon from '@nexub/brand/app-icon.svg';
import accountIcon from '@nexub/brand/app-icon-account.svg';
<AppLauncher apps={[
{ id: 'hub', name: 'Command Hub', href: 'https://hub.nexub.ai', icon: hubIcon },
{ id: 'account', name: 'Account', href: 'https://account.nexub.ai', icon: accountIcon, current: true },
]} />Vite inlines imports under 4 KB as data: URLs. img-src 'self' data: allows that; if your policy has no data:, see Strict CSP.
public/index.html and the web manifest need fixed URLs, so copy the files into public/brand/ before dev and build. Add public/brand/ to .gitignore: it's build output, not a copy you maintain.
// package.json
"scripts": {
"brand": "node -e \"require('fs').cpSync('node_modules/@nexub/brand/assets', 'public/brand', { recursive: true })\"",
"predev": "pnpm brand",
"prebuild": "pnpm brand"
}<!-- index.html -->
<link rel="icon" href="/brand/favicon.ico" sizes="48x48" />
<link rel="icon" href="/brand/app-icon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/brand/app-icon-192.png" />
<link rel="manifest" href="/manifest.webmanifest" />// public/manifest.webmanifest
{
"name": "Nexub Command Hub",
"short_name": "Command Hub",
"icons": [
{ "src": "/brand/app-icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/brand/app-icon-512.png", "sizes": "512x512", "type": "image/png" }
]
}For the Account app, use the app-icon-account* files in these places.
With no bundler, copy the files next to your HTML in your deploy step (the same cpSync line, with your output folder, e.g. dist/brand) and reference them as /brand/<file>. Self-hosted files are same-origin, so a strict img-src 'self' needs no change.
Every product uses the same tile with its own glyph; don't edit the tile. In the nexub-ds repo:
packages/brand/glyphs/<product>.svg. Keep it inside roughly x/y 90–422, where the mark sits. Put gradients in a <defs> with id="glyph" (see glyphs/account.svg).{ id: '<product>', glyph: read('glyphs/<product>.svg'), halo: '<hex>' } to PRODUCTS in packages/brand/scripts/build-assets.mjs. halo tints the glow behind the glyph.pnpm --filter @nexub/brand build:assets, commit assets/app-icon-<product>*, and release. The tile then ships as @nexub/brand/app-icon-<product>.svg plus 192 and 512 px PNGs.