GioJSdocs
On this page

public/

Static files the Rust server serves as they are, at the site root and under /public/, before any page renders.

text
public/
  favicon.ico                 /favicon.ico               and /public/favicon.ico
  robots.txt                  /robots.txt                and /public/robots.txt
  images/hero.webp            /images/hero.webp          and /public/images/hero.webp
  .well-known/security.txt    /.well-known/security.txt  and /public/.well-known/security.txt

Reference

Location

The public/ folder next to app/. GIO_PUBLIC_DIR points the server at another directory.

URLs

URLWhat is servedCaching
The site root: public/a/b.png at /a/b.pngRegular files, GET and HEAD only, except dotfiles (other than the top-level .well-known/), symlinks and a top-level public/_gio/Cache-Control: public, max-age=0, must-revalidate and Last-Modified
/public/ + the path: /public/a/b.pngEvery file in the folder, dotfiles and symlinks included; a folder URL (/public/docs/) serves that folder's index.htmlLast-Modified, no Cache-Control

Both answer conditional and range requests, with a Content-Type from the file extension, and X-Gio-Cache: static. Neither ever reaches the Node worker or the page cache.

Precedence

  • A file at the site root wins over a page or route.ts with the same path: the server answers before routing.
  • It also wins over app/sitemap.ts, app/robots.ts and app/manifest.ts, which then never run; startup warns about each.
  • Guards, header rules and [[rate_limits]] written for a file's /public/... URL also apply at its root URL, so protecting /public/members/*rest protects /members/... too.

The root index

Which files answer at the root is decided by an index the server builds at startup, so a request never costs a filesystem lookup. In development, changes under public/ refresh it and reload open browser tabs (the worker does not restart). In production a file added after startup answers under /public/ right away and at the root after the next restart. The index holds up to 100,000 files; any beyond that are served under /public/ only.

Examples

A favicon and a touch icon

app/layout.tsx
import React from 'react';
import type { LayoutProps, Metadata } from '@gio.js/core';

export const metadata: Metadata = {
  icons: {
    icon: '/favicon.ico',
    apple: '/apple-touch-icon.png',
  },
};

export default function RootLayout({ children }: LayoutProps) {
  return (
    <html lang="en">
      <head />
      <body>{children}</body>
    </html>
  );
}

With public/favicon.ico and public/apple-touch-icon.png in place, browsers that request /favicon.ico without reading the page find it too.

Optimized images from public/

tsx
import { GioImage } from '@gio.js/react';

<GioImage src="/images/hero.webp" alt="" width={1200} height={600} priority />

<GioImage> resizes files from public/ through /_gio/image; src may be the root URL or the /public/ one.

Good to know

  • Everything in public/ is public. Dotfiles are kept off the root, but stay reachable under /public/: never put .env files, keys or backups there.
  • File names carry no content hash, so browsers revalidate root files on every use. For assets that should be cached for a year, reference them from CSS (url(./bg.png) next to an imported stylesheet is copied with a hashed name) or put a version in the file name.
  • Directory listings are never served. public/index.html does not answer / (only /public/ and /index.html), so it never competes with app/page.tsx.
  • gio export copies the folder to out/ and out/public/, so static hosts serve the same URLs; a file whose output path a rendered page needs is skipped, and the export says so. gio build standalone ships the folder in the deploy directory.
  • Local [[fonts]] are read from public/ (url = "/public/fonts/inter.woff2") and served from /_gio/fonts/ under a content-hashed name.
  • A path with an encoded slash (%2F) or backslash under /public/ is refused with 400, and never matches a root file: the rules for /members/*rest could not see it.

Version history

VersionChanges
v0.1.0-beta.8Files are also served at the site root, ahead of pages, with max-age=0, must-revalidate; dotfiles (except .well-known/), symlinks and public/_gio/ stay off the root. The folder defaults to the one next to app/. Rules for /public/... URLs cover the root URLs.
v0.1.0-beta.1Introduced: files served under /public/.