SDK

React hooks

Read Myna content from React components with request sharing, stale-while-revalidate, preview propagation, and Suspense.

@myna-sh/react provides hooks for reading content in React components. It wraps the public client and adds request sharing, loading and error state, stale-while-revalidate caching, and preview-token propagation.

React and @myna-sh/sdk are peer dependencies; the package has no others.

$ npm install @myna-sh/react @myna-sh/sdk

Setup

Create a client and pass it to MynaProvider:

import { createMyna } from "@myna-sh/sdk";
import { MynaProvider } from "@myna-sh/react";
import type { MynaCollections } from "./myna.generated";

const myna = createMyna<MynaCollections>({
  project: "my-site",
  previewToken: new URLSearchParams(location.search).get("preview") ?? undefined,
});

<MynaProvider client={myna}>
  <App />
</MynaProvider>;

Every hook under the provider uses that client, including its preview token — so previewed and published pages render through the same components.

Hooks

import { useMynaEntries, useMynaEntry, useMynaSingleton } from "@myna-sh/react";

const posts = useMynaEntries<MynaCollections>("posts", { order: "-publishedAt", limit: 20 });
const post = useMynaEntry<MynaCollections>("posts", slug);
const settings = useMynaSingleton<MynaCollections>("site-settings");
Hook data
useMynaEntries(collection, options?) { data: Entry[], nextCursor }
useMynaEntry(collection, slugOrId, options?) One entry
useMynaSingleton(collection, options?) A singleton's entry

Each returns:

Field Type Meaning
data T | undefined The result, once loaded
error Error | undefined The most recent failure
isLoading boolean No value yet
isValidating boolean Refreshing with a value already on screen
refetch () => void Discard the cached value and reload

Pass undefined as slugOrId and useMynaEntry waits instead of fetching — useful while a route parameter resolves.

Options

Hooks accept every read option the SDK does — order, filter, fields, include, representation — with the same generated-type checking, plus:

Option Default Meaning
enabled true Set false to skip the read
staleMs 30000 How long a cached value is served before a background refresh
suspense false Throw the pending promise for a <Suspense> boundary

Behavior

Requests are shared. Components requesting the same collection with the same options produce one HTTP request — while in flight, and again within staleMs.

A failed refresh keeps the previous value. When a background refresh fails, data holds the last successful result and error is set. Render both if you want to show a staleness indicator.

Preview tokens propagate. A token on the provider's client applies to every hook beneath it. Reads return the collection as it would be published: updated entries replaced, created entries present, removed entries absent.

Using another data library

If your app already uses TanStack Query or SWR, call @myna-sh/sdk from it directly rather than adding these hooks — two caches holding the same content will disagree.

Server rendering and build-time reads

These hooks run on the client. For route loaders, server components, or static generation, call the SDK directly:

import { createMyna } from "@myna-sh/sdk";

const myna = createMyna<MynaCollections>({ project: "my-site" });

export async function loader() {
  const posts = await myna.entries.list("posts", { order: "-publishedAt" });
  return { posts: posts.data };
}

Responses carry an ETag and Cache-Control: public, max-age=0, must-revalidate, so a CDN or framework cache revalidates with a conditional request. To rebuild a static site when content changes, subscribe a deploy hook to the change_set.published webhook event.