Historical documentation Bundle v1.1.28 Core v1.1.28 Distribution v0.3.30 Released 2026-11-08T00:00:00Z
Release history
Native CSS and shared fonts Portable source contracts, adoption guidance and compatibility limits for native css and shared fonts. v1.1.28 core current site-builderscore-developersintegratorsai-agentsmaintainers

core · Current reference

Native CSS and shared fonts

Portable source contracts, adoption guidance and compatibility limits for native css and shared fonts.

Applies to v1.1.28

Component pins for v1.1.28
ComponentRoleVersion
coreruntimev1.1.28
theme-shieldthemev0.1.17
docsreferencev0.1.6
distributiontoolingv0.3.30

Core v1.1.21 exposes ordered Hugo resources so a site can bundle its styles without copying the framework’s asset list. The normal build uses Hugo Extended 0.165.0 and Go 1.27. No browser, Control service, font compiler or Node runtime is required. Existing css.html, theme and override calls remain compatible.

Human path

With Shield v0.1.17, opt into the whole-head CSS collector in site configuration:

params:
  foundry:
    assets:
      css_mode: bundled
      font_profile: shared-full

CSS and fonts are independent options. Omit font_profile to retain the small attribution-subsets default. Shield defaults to css_mode: individual; its legacy discovery behavior is unchanged. The explicit bundled path calls the Core partial directly and does not depend on that legacy discovery guard. Unknown Shield modes and attribution font profiles fail the build.

A custom shell can call {{ partial "foundry/head/styles.html" . }} once where its styles belong. This replaces its calls to css.html, theme CSS and foundry/head/site-overrides-css.html; calling both paths duplicates styling. Keep SEO, scripts, image preloads and unrelated head hooks in their own places.

Add the return-only site hook at layouts/partials/site/foundry-styles.html (or Hugo’s _partials/site/ form):

{{- $styles := slice (dict "id" "site-brand" "resource" (resources.Get "css/brand.css")) -}}
{{- if .Params.gallery -}}
  {{- $styles = $styles | append (dict "id" "site-gallery" "resource" (resources.Get "css/gallery.css")) -}}
{{- end -}}
{{- return $styles -}}

Use the site’s real conditions and order. An absent hook means no page bundle. The hook is a site extension, outside the Core partial namespace; no shadow allowlist or copy of Core internals is needed. Each entry needs a unique id and a real Hugo CSS resource. Missing or duplicate inputs fail clearly.

Cascade and identity contract

foundry/assets/core-styles.html returns ordered descriptors for syntax, base, conditional theme-family CSS, motion, flow, creative, search, forms and the existing optional processed main stylesheet. It emits no markup. The legacy css.html uses foundry/assets/individual-styles.html to retain individual resource paths, development behavior and production minification/integrity. The legacy optional Tailwind compatibility transform is retained; selecting it is outside the native Node-free path and remains subject to the site’s tooling policy. This release does not install or execute that toolchain.

foundry/assets/collect-styles.html returns two groups, each with id and an ordered styles slice. foundation is Core, optional css/theme.css, then nonempty css/foundry-overrides.css. page is exactly the site hook’s entries. foundry/assets/bundled-styles.html emits one blocking stylesheet per nonempty group in that order. Every link has fingerprinted URL, integrity, anonymous crossorigin, data-foundry-styles and ordered data-style-sources attributes. No asynchronous CSS, coverage pruning or motion changes occur. Feature partials such as appearance/preferences keep their existing demand-driven CSS emitters; the collector replaces the common css.html/theme/override chain, not every stylesheet that any shortcode or helper may emit. Such pages can legitimately have more than two stylesheet links. Do not pull all optional helper CSS into every foundation merely to obtain a fixed request count.

Targets contain the SHA256 of ordered resource names and content hashes before Hugo concatenation. Foundation can be cached across routes while page or language variants cannot collide merely because they share descriptor IDs. Hugo’s resources.FromString also caches by target: site-generated resources must use a content/variant-specific target if their contents differ within one build.

Bundling does not rebase relative URLs. Supply fingerprinted resource RelPermalink values or root-relative, fragment, data or absolute URLs. Relative url(...) values and unresolved @import, @charset, @namespace directives are rejected in the bundled path. Resolve imports and font/image resource URLs before returning the resource. The legacy path is unchanged. These checks are conservative and may also reject such syntax inside CSS comments; remove those comments or prepare a bundle-safe resource. Do not change public cache/security policy merely to adopt this output.

Optional site-wide foundation CSS

params.foundry.assets.foundation_profile: site opts a static production build into the site-wide union of reviewed portable component styles. The default is full. This option works with the native bundled and individual emitters; existing custom resource collectors retain their existing full-base behavior. It changes neither fonts nor motion scripts. Stylesheet links remain synchronous in the head, in their original cascade order. Native Hugo build-time deferral resolves the union after page rendering; no browser coverage sample or client stylesheet loader is involved. Normal Hugo builds need no extra tool.

Core registers the actual rendered HTML returned by its section renderer, including nested and registered custom section partials. Native article media and newsletter helpers register their own rendered block output when they bypass that section path. Core also includes the site’s Markdown and shortcode content. A present component retains every scoped rule for its family, including responsive, reduced-motion, hover, focus, open, paused and runtime child states. Shell, generic/editorial content, unknown or mixed selectors, keyframes and other global rules remain shared. The profile can reduce transfer on a site that uses only part of Core’s component inventory; the result depends on the whole site’s content and its theme.

For custom markup outside those paths, explicitly register the returned HTML:

{{- $html := partial "site/custom-component.html" . -}}
{{- partial "foundry/assets/register-foundation-scopes.html" (dict "html" $html) -}}
{{ $html }}

A script that inserts a whole component after build time must declare it in foundation_extra_scopes. Extra scopes are a site-level union, not page-level coverage. The reviewed namespace list is machine-readable in data/foundry/foundation-css-scopes.json; unknown entries fail the build:

params:
  foundry:
    assets:
      foundation_profile: site
      foundation_extra_scopes:
        - foundry-media-sequence
        - foundry-routing-panels

Custom headers, shortcodes, layouts and external scripts remain visible, site-owned dependencies. If their component usage cannot be bounded, keep foundation_profile: full. Do not copy Core’s asset list or selector parser into the consumer. Registration is a render-time helper and must not itself be called inside a deferred content block. Do not cache a head partial containing the deferred emitter with partialCached; cache its data or resource inputs instead. Hugo rejects deferred placeholders inside a cached partial.

Development, hugo server and Foundry preview-metadata builds deliberately retain full CSS for editing. Qualify this option with a static production build, so that fallback cannot conceal missing dependencies. A custom/stale canonical base override also retains the full base and warns. A changed generated template with an unchanged source fails clearly. Maintainers edit only the canonical assets/css/foundry-base.css, then run python3 scripts/build-foundation-css.py and its --check mode; the generated template preserves original declaration and rule order. A full-enabled projection is tested byte for byte against that canonical source. A Core helper rendering an optional block outside the section path must register that returned HTML and test it without another page enabling the same family. Unknown future syntax remains shared rather than guessed.

Before adoption, compare all routes, custom dependencies, native navigation, forms, fonts, motion controls, offscreen content, reduced motion, no-JavaScript and startup layout shift at desktop/mobile/reflow sizes. Full mode is the configuration rollback. Shared payload savings do not establish a live Lighthouse score or field Web Vitals; the consumer owns that measurement.

One font registry, two delivery profiles

foundry/assets/font-registry.html returns a map keyed by the original filename stem: Newsreader72pt-Regular, Newsreader72pt-Italic, SourceSans3-Regular and SourceSans3-Semibold. Each entry preserves the metadata in assets/fonts/foundry-attribution/delivery.json and adds id, resource (fingerprinted full original) and subset_resource (fingerprinted derivative). Accessing a resource object alone does not publish it; using its permalink does. There is no second font manifest and no changed font/licence bytes.

Brand CSS can use full originals through foundry/assets/font-face.html:

{{- $face := partial "foundry/assets/font-face.html" (dict "id" "Newsreader72pt-Regular" "family" "My Display") -}}
{{- $css := printf "%s\nh1{font-family:'My Display',Georgia,serif}" $face -}}
{{- $resource := resources.FromString "css/site-type.css" $css -}}
{{- return (slice (dict "id" "site-type" "resource" $resource)) -}}

The helper emits a full original face with its verified weight/style and font-display:swap. It never substitutes the phrase subsets for brand text. Use the registry’s resource.RelPermalink for a justified site-owned preload; no new preloads are automatic. Fonts not in this registry remain site-owned.

ProfileAttribution deliveryIntended use
attribution-subsets (default)Existing disjoint subset/original ranges; original Sans for dynamic detailsSites using other brand fonts; three closed-footer requests total 37,732 bytes, under 40,000-byte budget
shared-full (opt-in)Original full masters, isolated attribution family aliases, same URLs as brand helperSites already using these original typefaces; avoids adding separate phrase subset requests

Default expanded details intentionally add original Sans Regular, for a combined 147,364 bytes. Full profile’s three ordinary footer styles total 205,708 bytes; all four original masters total 314,608 bytes if the page also uses Semibold. CSS declarations do not mean every face downloads. Full profile can increase bytes on a site using other fonts, and is not the default. Both profiles retain one original Sans face for arbitrary dynamic values and multilingual/combining shaping. Attribution keeps its own CSS family aliases and appearance isolation; brand styling does not inherit into it. Identical URLs, not alias spelling, provide browser resource reuse. No scripted font loader, data URI or remote font service is involved.

Migration and proof

Replace a consumer’s repeated Core/theme/override list with the whole-head call, then return only its own conditional CSS. Replace copied font URL assembly with the registry or full-face helper. Keep other site fonts, brand rules and motion policy. Check emitted resource order, page variants, startup layout shift, no-JavaScript content, reduced motion, menu/focus and attribution details at mobile, desktop and reflow widths before deployment. A successful build or a shared release alone does not prove a consumer’s live performance.

Visual Change Protocol governs shared changes; Consumer Integration Quality Gate governs adoption. Foundry Control can add managed review, publishing and care around this portable source contract; normal Hugo builds remain independent of it.

Static Pagefind search

Search Foundry documentation

Type at least two characters
Search the full documentation system

Results stay inside this build profile and can be filtered by version, component, audience, and lifecycle.

ByLikeStyle
Site details
Site release
Foundry Documentation v1.3.14
Foundry bundle
v1.1.29
Foundry Core
v1.1.29
Credit
Powered by Foundry, a LikeStyle product.