SDK packages
The packages a site reads Mapled through — what each one adds and the first read in each.
Every package reads the same thing — the latest published release, through the delivery API, with the project's delivery key — and has no dependencies beyond @mapled/client. They differ in what they add around the reads for their stack.
| Package | For | Adds |
|---|---|---|
@mapled/next | Next.js, App Router and Pages Router | ISR cache tags, the publish webhook handler, draft-mode preview, live updates for open tabs, forms, live data, site users |
@mapled/astro | Astro | A server-side client with a tag cache, the webhook (purge or rebuild), preview, live updates |
@mapled/nuxt | Nuxt | A Nuxt module with the same: client, cache (Nitro's too), webhook, preview, live updates |
@mapled/react | React single-page apps | MapledProvider and three hooks; preview and live updates in the browser |
@mapled/vanilla | Plain HTML | One script tag and data-mapled-* attributes; the page's own HTML is the fallback |
@mapled/client | Any JavaScript runtime | The reads, preview in the browser, release watching, forms, live data |
Image and file fields hold asset ids: assetUrl(id, { width }) turns one into a URL, resized on the first request — from @mapled/next, @mapled/astro, @mapled/nuxt or @mapled/client (a React app imports it from @mapled/client; plain HTML binds images with attributes). Rich text is Markdown: render it with a Markdown component, never as raw HTML.
npx @mapled/cli types generate writes mapled-types.ts — one interface per collection and single, tied together by MapledSchema — and every TypeScript package takes it, so a misspelled collection or field is a build error. Plain HTML has no build: the page's report (Mapled.page.report) names the bindings that found nothing — a collection that isn't there reads missing, and a misspelled field reads empty, like a field an editor left empty.
@mapled/next
npm install @mapled/next
// lib/mapled.ts
import { createClient } from "@mapled/next";
import type { MapledSchema } from "../mapled-types";
export const mapled = createClient<MapledSchema>({ key: process.env.MAPLED_KEY! });
Read in Server Components; reads are cached and tagged, and the webhook handler refreshes them on publish. The whole integration: Next.js, step by step. Every export: README.
@mapled/astro
npm install @mapled/astro
// src/lib/mapled.ts
import { mapled } from "@mapled/astro";
import type { MapledSchema } from "../mapled-types";
/** Pass `Astro` (or an endpoint's context) so the request's preview cookie is seen; without it, published content only. */
export const cms = (from?: Request | { request: Request }) => mapled<MapledSchema>(from, { key: import.meta.env.MAPLED_KEY });
Pages that read Mapled render on demand, or a static build is rebuilt by the publish webhook through your host's deploy hook. README.
@mapled/nuxt
npm install @mapled/nuxt
// nuxt.config.ts
export default defineNuxtConfig({
modules: ["@mapled/nuxt/module"],
});
The module mounts the webhook, the preview routes and the release route under /api/mapled, and gives pages the useMapled() composable and the <MapledLive /> component. README.
@mapled/react
npm install @mapled/react
// src/mapled.ts
import { createClient } from "@mapled/client";
import { typedHooks } from "@mapled/react";
import type { MapledSchema } from "./mapled-types";
export const mapled = createClient<MapledSchema>({ key: import.meta.env.VITE_MAPLED_KEY });
export const { useSingle, useRecords, useRecord } = typedHooks<MapledSchema>();
Wrap the app in <MapledProvider client={mapled}>; every hook answers { data, loading, error, refetch }. The key lives in .env as VITE_MAPLED_KEY — it is bundled into the page, which is fine for the delivery key and for no other. README.
@mapled/vanilla
<!-- index.html -->
<!doctype html>
<html lang="en">
<head>
<title data-mapled-bind="home.headline">Studio Nord</title>
<script src="https://cdn.jsdelivr.net/npm/@mapled/vanilla@0.2.3/dist/mapled.js" data-mapled-key="mk_live_…" defer></script>
</head>
<body>
<h1 data-mapled-bind="home.headline">Websites, built by hand</h1>
</body>
</html>
home.headline is the field headline of the single home. Until the script has read the live release — and whenever Mapled can't be reached — the page shows what you wrote. Pin the version in the address. Lists, one record per page, links, images, forms and every attribute: README.
@mapled/client
npm install @mapled/client
// src/content.ts
import { createClient } from "@mapled/client";
const mapled = createClient({ key: "mk_live_…" });
const home = await mapled.getSingle("homepage");
const { records, total } = await mapled.getRecords("posts", { sort: "-date", limit: 10, expand: ["author"] });
const post = await mapled.getRecordBySlug("posts", "hello-world");
Runs in a browser, Node or an edge function. README.
Reads
Every package reads with the same options:
getRecords(collection, { filter, sort, limit, offset, expand, fields, search, locale, release })— a list withtotal;getRecord(collection, id),getRecordBySlug(collection, slug)— one record, ornull;getSingle(key)— a single, ornull;getRelease()— the release being served now.
filter takes a value for equality or { eq, ne, lt, lte, gt, gte, in, contains }; sort is "field" or "-field"; expand follows relations two levels deep; locale reads one of the project's languages; release pins a read to one published release. The same queries over HTTP: HTTP API.