Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nuejs/nue/llms.txt

Use this file to discover all available pages before exploring further.

Nue treats CSS as a first-class citizen rather than a side effect of component rendering. Instead of scoping styles inside JavaScript components or generating utility class strings at build time, Nue relies on the browser’s built-in cascade — the mechanism CSS was designed around. Global stylesheets live next to your content, design tokens flow through custom properties, and every layer from reset to page-specific overrides has a predictable place.

Why CSS-first instead of CSS-in-JS

Modern frameworks commonly co-locate styles with components using CSS Modules, styled-components, or utility class libraries like Tailwind. Nue takes the opposite position: styles belong in .css files that are separate from markup and logic.

CSS-in-JS approach

Styles are coupled to component trees. Changing a global design token requires hunting through dozens of component files. The cascade is treated as a bug rather than a feature.

Nue's CSS-first approach

Styles live in dedicated files that any page or component can share. The cascade resolves specificity predictably, and updating a design token in one place propagates everywhere.
Nue avoids inline styles entirely. Inline styles have the highest specificity in CSS and cannot be overridden by external stylesheets, breaking the cascade contract. Utility-class approaches like Tailwind move design decisions into HTML attributes and make it difficult to see the full picture of how an element is styled across contexts.
The separation of concerns principle that guides Nue’s overall architecture — HTML for structure, JS for behavior, CSS for design — applies just as strictly to styling as it does to routing or data loading.

Global stylesheets and the @shared directory

Nue looks for CSS in a directory called @shared at the root of your project. Files placed here are automatically available to every page and application in your site. You do not need to import them explicitly.
my-site/
├── @shared/
│   └── design/
│       ├── reset.css
│       ├── tokens.css
│       ├── layout.css
│       ├── components.css
│       └── utilities.css
├── blog/
│   ├── blog.css
│   └── index.md
└── site.yaml
Use subdirectories inside @shared/design/ to keep layers organized. Nue loads them in filesystem order, so alphabetical or numbered prefixes give you explicit control over load order.

How the cascade works in Nue

Styles resolve in three layers of increasing specificity. Each layer narrows scope from site-wide to application-specific to page-specific.
1

Shared styles

CSS in @shared/ applies to the entire site. This is where your design tokens, base reset, typography scale, and reusable component styles live.
2

App styles

Each application directory (for example blog/ or store/) can include its own .css files. These apply to every page within that application and can override shared styles.
3

Page styles

A .css file with the same base name as a page file applies only to that page. about.css applies only to about.md. These overrides have the narrowest scope.
This layering mirrors standard CSS specificity without any custom tooling. You never need a !important rule or a scoping wrapper — you simply place your override at the right layer.

Design system layers

A complete Nue design system follows five layers, each with a distinct responsibility.
Strips browser default margins, paddings, and box model inconsistencies. Nue recommends a minimal reset that preserves meaningful defaults like rem-based font sizes.
/* @shared/design/reset.css */
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--color-text);
  background: var(--color-bg);
}

h1, h2, h3, h4, p, ul, ol {
  margin: 0;
}
CSS custom properties that encode your brand decisions: color palette, typography scale, spacing rhythm, border radius, and shadow depth. Tokens are the single source of truth for every visual decision.
/* @shared/design/tokens.css */
:root {
  /* Color palette */
  --color-bg: #ffffff;
  --color-text: #1a1a2e;
  --color-primary: #0d6efd;
  --color-muted: #6c757d;
  --color-border: #dee2e6;

  /* Typography */
  --font-body: 'Inter', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', monospace;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;

  /* Spacing */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-4: 1rem;
  --space-8: 2rem;
  --space-16: 4rem;

  /* Shape */
  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-lg: 1rem;
}
Grid and flex patterns for page-level structure: the main content area, sidebars, header, footer, and spacing between major sections.
/* @shared/design/layout.css */
.page-wrapper {
  display: grid;
  grid-template-columns: 1fr min(65ch, 100%) 1fr;
  padding-inline: var(--space-4);
}

.page-wrapper > * {
  grid-column: 2;
}

.full-bleed {
  grid-column: 1 / -1;
}
Reusable UI patterns like buttons, cards, navigation, and form elements. Component styles target semantic HTML elements and BEM-style class names, never deeply nested selectors.
/* @shared/design/components.css */
.card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}

.card-title {
  font-size: var(--font-size-lg);
  font-weight: 600;
  margin-bottom: var(--space-2);
}

.btn {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  font-weight: 500;
  cursor: pointer;
}

.btn-primary {
  background: var(--color-primary);
  color: #fff;
}
Single-purpose helper classes for spacing, text alignment, display, and visibility. Keep this layer small — utility classes that duplicate component styles create maintenance debt.
/* @shared/design/utilities.css */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
}

.text-center { text-align: center; }
.text-muted   { color: var(--color-muted); }
.mt-auto      { margin-top: auto; }

Semantic HTML and external CSS

Nue’s component model encourages writing semantic HTML. An article, a navigation list, and a figure are expressed as <article>, <nav>, and <figure> — not as <div class="article-wrapper">. This matters for styling because semantic elements carry implicit meaning that CSS selectors can target directly without extra classes.
<!-- Semantic markup: styled via external CSS -->
<article>
  <header>
    <h1>Getting started</h1>
    <time datetime="2025-01-15">January 15, 2025</time>
  </header>
  <p>Content goes here.</p>
</article>
/* @shared/design/components.css */
article {
  max-width: 65ch;
  margin-inline: auto;
}

article header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--space-8);
}

article h1 {
  font-size: var(--font-size-xl);
  font-weight: 700;
}

article time {
  color: var(--color-muted);
  font-size: 0.875rem;
}
When styles live in external files, you can restyle your entire site by editing a handful of CSS files without touching a single component or template.

File naming conventions

Consistent naming makes it easy to understand which CSS applies to which scope at a glance.
FileScopeExample
@shared/design/*.cssEntire sitetokens.css, layout.css
<app-dir>/<app-name>.cssOne applicationblog/blog.css
<page-name>.cssOne pageabout.css, contact.css
Prefix layer files with numbers when load order matters: 01-reset.css, 02-tokens.css, 03-layout.css. This makes the intended order explicit to both the filesystem and other developers.

Including and excluding CSS files

You can control exactly which CSS files are loaded using site.yaml. This is useful when a stylesheet is experimental, environment-specific, or should only apply under certain build conditions.
# site.yaml

# Include additional CSS files on every page
include:
  - "@shared/design/extra.css"
  - analytics.js

# Exclude a file from the build entirely
exclude:
  - "@shared/design/experimental.css"
The include array adds files to every page beyond those auto-discovered by Nue’s dependency resolver. The exclude array removes a file from all pages, useful for disabling a global stylesheet in specific scenarios.
Excluding a CSS file removes it from all pages, including pages that currently depend on styles it defines. Check for visual regressions before deploying.

Responsive design without a framework

Nue relies on standard CSS media queries and the cascade. No responsive utility classes, no breakpoint configuration in JavaScript — just CSS.
/* @shared/design/layout.css */

/* Base: single column */
.site-nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Medium screens: horizontal */
@media (min-width: 48rem) {
  .site-nav {
    flex-direction: row;
    gap: var(--space-4);
  }
}

/* Large screens: with sidebar */
@media (min-width: 72rem) {
  .page-layout {
    display: grid;
    grid-template-columns: 16rem 1fr;
    gap: var(--space-8);
  }
}
Because tokens hold your spacing and sizing values, responsive adjustments stay DRY — you update one token value and the change propagates to every responsive rule that references it.

Dark mode

Dark mode is a token swap, not a separate stylesheet. Override your color tokens under a prefers-color-scheme media query or a [data-theme="dark"] attribute:
/* @shared/design/tokens.css */
@media (prefers-color-scheme: dark) {
  :root {
    --color-bg: #0d1117;
    --color-text: #e6edf3;
    --color-primary: #58a6ff;
    --color-muted: #8b949e;
    --color-border: #30363d;
  }
}
No extra JavaScript, no CSS-in-JS theming API, no framework abstraction needed — the browser handles the rest.

Build docs developers (and LLMs) love