How Static Assets (Images, Fonts, etc.) Are Managed in Open SEO's Public Directory

Open SEO uses the public folder as an unprocessed, verbatim copy of static assets that Cloudflare Workers serve directly to browsers with efficient caching headers.

The every-app/open-seo repository follows Vite's standard convention for static asset handling. Files placed in the public directory bypass the build pipeline entirely and are deployed unchanged, making them instantly available via root-relative URLs.

What the Public Directory Does in Open SEO

The public folder serves as a drop-and-serve location for any file that should reach the browser exactly as authored. This includes logos, favicons, font files, SVG icons, and other immutable assets.

According to the source code in public/, the directory contains assets like transparent-logo.png and favicon.ico that require no transformation. Vite's default publicDir: "public" configuration ensures these files are excluded from bundling, hashing, or code splitting.

How Assets Move from Public to Production

The deployment flow for static assets in Open SEO follows three stages:

  1. Placement — Developers add files to public/ using any folder structure (e.g., public/fonts/, public/images/).

  2. Build-time copy — During wrangler deploy or Vite's build step, the entire public/ tree is copied verbatim into the Worker asset bundle. No file contents are modified.

  3. Automatic serving — Cloudflare Workers, configured via wrangler.jsonc, routes incoming HTTP requests to matching files in the bundled assets without custom handler code.

This means a request for /favicon.ico resolves directly to public/favicon.ico with no additional routing logic required.

Referencing Public Assets in Code

Open SEO components use root-relative paths that mirror the public/ folder structure. The browser requests these URLs directly from the Worker.

Images in React Components

export const Logo = () => (
  <img src="/transparent-logo.png" alt="Open SEO" width={120} />
);

The src="/transparent-logo.png" path corresponds exactly to public/transparent-logo.png in the repository.

Fonts in CSS

@font-face {
  font-family: 'OpenSans';
  src: url('/fonts/OpenSans-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
}

Place font files in public/fonts/ and reference them with leading slashes to ensure correct resolution.

Favicons and Static Files

<link rel="icon" href="/favicon.ico" />

No import statements or build-time processing applies—the file is served byte-for-byte as stored in public/.

Caching Behavior for Static Assets

Open SEO configures Cloudflare Workers to serve public assets with aggressive caching headers. The static-asset response includes:


Cache-Control: public, max-age=86400, immutable

This header pattern, derived from Vite's default route configuration for scripts, applies equally to files copied from public/. The immutable directive tells browsers these files will never change at their URL, allowing indefinite caching without revalidation requests.

Key Configuration Files

Understanding these files clarifies how the public directory integrates with Open SEO's deployment:

File Role
public/transparent-logo.png Example image served unchanged
public/favicon.ico Standard favicon asset
wrangler.jsonc Cloudflare Workers config that bundles public/ as static assets
vite.config.ts Implicit publicDir: "public" setting; no customization required

Summary

  • Unprocessed placement: Files in public/ are copied verbatim, never bundled or hashed by Vite.
  • Direct serving: Cloudflare Workers automatically map URL paths to public/ files via wrangler.jsonc configuration.
  • Root-relative URLs: Always reference assets with leading slashes (e.g., /logo.png).
  • Immutable caching: 24-hour max-age with immutable directive maximizes browser caching efficiency.
  • Zero handler code: No explicit TypeScript routing required for static asset requests.

Frequently Asked Questions

Can I use subdirectories inside the public folder?

Yes. Create any folder structure needed—public/fonts/, public/images/, public/icons/—and reference assets with the full path: /fonts/OpenSans.woff2 resolves to public/fonts/OpenSans.woff2.

Why not import images directly in components?

Vite-processed imports trigger bundling, hashing, and potential optimization. The public directory bypasses this intentionally for files that should remain unchanged or require predictable URLs, such as robots.txt, manifest.json, or fonts referenced in global CSS.

Do public assets require special Cloudflare Workers routing?

No. The wrangler.jsonc configuration in Open SEO automatically handles static asset serving. A request to /any-file.png checks the bundled public assets before falling through to application routes—no explicit worker code needed.

What happens if a public asset is missing?

The Cloudflare Worker returns a 404 response for unmatched paths. Since public/ assets are served before application logic executes, missing files do not reach your React router or API handlers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →