Skip to content

Site architecture

Studio manages this structure for youBrowse your project maps to pages/ , components/ , and content/ ; the content-type builder writes the content section; Project settings edits project.json . This section documents the on-disk layout for reference.

A Jx site is a folder of plain JSON and Markdown files with a conventional layout. Only project.json and pages/ are required — everything else is optional and additive.

Project anatomy

my-site/
├── project.json           # Site configuration (required)
├── pages/                 # File-based routing (required)
│   ├── index.json         # → /
│   ├── about.json         # → /about
│   └── blog/
│       ├── index.json     # → /blog
│       └── [slug].json    # → /blog/:slug (dynamic)
├── layouts/               # Shared page shells
│   └── base.json
├── components/            # Reusable Jx components
├── content/               # Content collections
│   └── blog/
│       └── hello-world.md
├── data/                  # Static data files
├── public/                # Static assets (copied verbatim)
└── dist/                  # Build output (generated)
Directory Purpose Required
pages/ File-based routing. Each page file becomes a route. Yes
layouts/ Layout components, referenced by pages via $layout . No
components/ Reusable components, referenced via $ref or $elements . No
content/ Content collections with schema validation. No
data/ Static data files loaded at build time. No schema enforcement. No
public/ Static assets copied verbatim to dist/ . No processing. No
dist/ Build output. Ignored by git. Generated

Files and directories whose names start with _ inside pages/ are excluded from routing, so components can live next to the pages that use them ( pages/blog/_blog-card.json ).

Configuration

project.json at the project root is the only required configuration file. It names the site, sets the default layout and language, declares global <head> entries, breakpoints, and design tokens, and holds the content , redirects , copy , and build sections — plus any section an enabled extension contributes: connections and data for databases, auth for visitor accounts, search for the build-time search index. Site-level state and $defs cascade into every page. See project.json .

Routing

Every file in pages/ becomes a route automatically: pages/about.json serves /about , pages/blog/[slug].json is a dynamic route with a slug parameter, and pages/docs/[...path].json catches everything under /docs/ . Dynamic pages declare the concrete paths they generate with $paths — usually by pointing at a content collection. See Routing .

Layouts

Layouts are ordinary Jx documents that provide the shared page shell — navigation, footer, and the <slot> elements where page content lands. Pages opt in with $layout , or inherit the site default. Named slots, nesting, and state merging follow the same rules as custom elements. See Layouts .

Content collections

The content section of project.json turns folders of Markdown, JSON, or CSV files into typed, queryable collections with JSON Schema validation. Pages query them with ContentCollection and ContentEntry state entries, and schema $ref s link entries across collections — see Content collections and Relationships .

Markdown pages and content

Markdown is a first-class authoring format: content entries and even whole pages ( pages/index.md ) can be written in Jx Markdown, with frontmatter for metadata and directives for embedding components. See Jx Markdown .

SEO and metadata

Pages declare <head> entries with $head , merged in a fixed order with layout- and site-level entries; titles, canonical URLs, sitemaps, and structured data are handled at build time. See SEO and metadata .

Images

Images referenced from pages and content are optimized during the build — resized to multiple widths and re-encoded to modern formats, configured by the images section of project.json . See Images .

Redirects

The redirects map in project.json declares old-URL-to-new-URL rules, including :param patterns and per-rule HTTP status codes. See Redirects .

Databases, accounts, and server functions

Not everything a site shows has to be a file. With the @jxsuite/connector extension enabled, connections names the databases the site talks to and data declares the tables inside them, served over /_jx/data ; with @jxsuite/auth , the auth section gives visitors accounts and sessions at /_jx/auth and unlocks the table permission rules that depend on knowing who is asking. Separately, any state entry marked timing: "server" compiles into its own route at /_jx/server/<export> , so secrets and privileged calls stay off the client. The connection-backed sections require a server-capable build.adapter — the build stops without one — and server functions need somewhere to run for the same reason. See Databases , Auth and secrets , and Timing .

Building and deploying

bunx jx build discovers routes, compiles each page, and emits static HTML, CSS, and minimal JS into dist/ — deployable to any static host. With build.adapter set, the same command also bundles the site's server tier — timing: "server" functions and extension mounts such as /_jx/data and /_jx/auth — into one self-contained worker. Pages are prerendered either way; the worker only answers /_jx/* and, on some adapters, serves the static files. See the build pipeline and Deployment ; Studio itself never runs this step — it commits and pushes your source , and your host builds on push.