Skip to content

Schema & Codecs

Zynq represents URL state as a schema of codecs. Each key in the schema maps to a query parameter; each codec defines the type and how values are encoded/decoded to and from strings.

Schema builder s

From @zynq/core, use the s object to build your schema:

ts
import { s } from '@zynq/core'

const schema = {
  page: s.number(1),
  search: s.string(''),
  active: s.boolean(false),
  since: s.date(new Date()),
  tags: s.array(s.string(), []),
  filters: s.object({
    min: s.number(0),
    max: s.number(100),
  }),
}

Every codec has a default value. When the query param is missing or invalid, that default is used.

Available codecs

CodecExampleDefaultEncoded in URL
s.string(default?)s.string('')''As-is
s.number(default?)s.number(1)0String number
s.boolean(default?)s.boolean(false)false'true' / 'false'
s.date(default?)s.date(new Date())new Date()ISO string
s.array(codec, default?)s.array(s.string(), [])[]Comma-separated (each item encoded by inner codec)
s.object(shape)s.object({ x: s.number(0) })from shapeJSON
  • string — Stored and read as-is; empty or missing uses default.
  • number — Encoded as string; invalid/missing falls back to default.
  • boolean — Encoded as 'true' / 'false'; any present value is truthy.
  • date — Encoded as ISO date string; invalid/missing uses default.
  • array — Items encoded with the inner codec and joined by ,. Empty/missing yields default array.
  • object — Encoded as JSON; invalid/missing yields default object from the shape.

Inferred types

Use InferSchema to get the TypeScript type of the state described by your schema:

ts
import { s, type InferSchema } from '@zynq/core'

const schema = {
  page: s.number(1),
  search: s.string(''),
}

type UrlState = InferSchema<typeof schema>
// { page: number; search: string }

Framework integrations (e.g. useZynq in Vue) use this so state is typed automatically.

Usage in frameworks

  • Vue — Pass the schema to useZynq(schema); you get reactive state with this type.
  • React / Angular — Same schema will be used with the framework-specific hook or service; state type is inferred from the schema.

See Engine & Router for how the core uses the schema to parse and serialize the URL.