Créez votre première application
Ce parcours construit une application bext PRISM minimale à partir de zéro : la générer, examiner les deux fichiers de configuration, ajouter un layout racine et une page dont le loader lit la session et appelle le SDK de la plateforme, puis l'exécuter localement avec rechargement à chaud. Quand vous serez prêt à la mettre sur un domaine, poursuivez avec Déployer un site PRISM.
Générer le squelette
Créez une nouvelle application à partir du modèle de démarrage PRISM :
bext new my-app --template @bext/starter-prism
cd my-app
Cela met en place un paquet de workspace : bext.config.toml, tsconfig.json, une
arborescence de routes src/app/ et un répertoire public/ pour les ressources statiques.
D'autres modèles de démarrage existent (-blog, -docs, -saas, -api) — voir la
Référence CLI.
Les fichiers de configuration
bext.config.toml
Le modèle de démarrage fournit une configuration minimale. Elle déclare une application PRISM qui surveille ses répertoires source pour le rechargement à chaud et effectue le rendu avec l'ISR :
[server]
app_dir = "."
static_dir = "public"
[framework]
type = "prism"
[build]
watch_dirs = ["src/app", "src/components", "src/lib"]
live_reload = true
[rendering]
mode = "isr"
revalidate = 600
Voir la Référence de configuration pour chaque section.
tsconfig.json
PRISM compile le JSX directement en chaînes de caractères, la configuration TypeScript pointe donc le JSX vers le framework :
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@bext-stack/framework",
"moduleResolution": "bundler",
"paths": { "@/*": ["./src/*"] }
}
}
Le layout racine
Le layout.tsx racine possède le document <html> et reçoit la page en tant que children.
Chaque fichier qui utilise du JSX commence par le pragma du framework :
/** @jsxImportSource @bext-stack/framework */
export default function RootLayout({ children }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<title>My App</title>
</head>
<body>{children}</body>
</html>
);
}
Un composant est simplement une fonction renvoyant une chaîne
((props) => string | Promise<string>) ; rien n'est envoyé au navigateur tant que vous
n'ajoutez pas d'island.
Une page avec un loader
Un page.tsx effectue le rendu de la route. Placez le chargement des données dans un
loader — le composant de page ne voit jamais request, les cookies et les en-têtes se
lisent donc dans le loader. Ici, le loader lit la session et incrémente un compteur dans le
magasin KV via le SDK loopback :
/** @jsxImportSource @bext-stack/framework */
import { createSdk } from "@bext-stack/framework";
import { readSession } from "@/lib/session";
const sdk = createSdk("my-app");
export async function loader({ request }) {
const session = readSession(request);
const visits = Number((await sdk.kv.get("visits")) ?? 0) + 1;
await sdk.kv.set("visits", visits, 3600); // valeur + TTL (secondes)
return { user: session?.user ?? null, visits };
}
export default function Page({ data }) {
return (
<main>
<h1>Hello{data.user ? `, ${data.user.name}` : ""}</h1>
<p>Page views: {data.visits}</p>
</main>
);
}
La valeur de retour du loader arrive sur la page en tant que props.data. Voir
Loaders et actions pour le cycle de vie complet — y compris action
pour les mutations, qui s'exécute avant le loader sur POST/PUT/PATCH/DELETE.
createSdk("my-app") atteint le SDK de la plateforme via l'interface loopback de confiance en
utilisant votre app id — aucun token admin requis. Il cantonne toutes les données à cet app id.
Appeler l'API de la plateforme depuis un loader
Un loader peut aussi appeler l'API de plateforme tRPC. Les requêtes sont
en GET avec une enveloppe d'entrée superjson, et le résultat que vous voulez est imbriqué à
result.data.json. Comme le loader détient request, il peut transférer le cookie de session
de l'appelant (__Secure-authjs.session-token) pour s'authentifier, puis lire la session avec
auth.getSession :
export async function loader({ request }) {
const res = await fetch(
"https://manage.inklura.fr/api/trpc/auth.getSession",
{ headers: { cookie: request.headers.get("cookie") ?? "" } },
);
const body = await res.json();
return { me: body.result.data.json };
}
Pour un client autonome complet — @trpc/client typé, pagination et gestion des erreurs —
voir Appeler l'API depuis un script.
Exécutez-la
Démarrez le serveur de développement avec rechargement à chaud :
bext dev
Il sert sur http://127.0.0.1:3000 par défaut. Options utiles : --port N,
--listen host:port, --open, --no-hmr. Modifiez un fichier sous watch_dirs et le
changement est pris en compte en une ou deux secondes. Pour voir les routes découvertes :
bext routes
Une note sur les paquets npm
Le bundler PRISM ne résout pas les spécificateurs npm nus dans l'isolate de rendu, et
l'isolate n'a aucun module natif Node. Un simple import "some-pkg" pour un paquet non
vendorisé échoue au moment du rendu. Vendorisez plutôt une build ESM en pur JS sous forme de
fichiers .js relatifs et importez-la par chemin relatif — voir la
Vue d'ensemble du SDK.
Étapes suivantes
| Page | Ce qu'elle couvre |
|---|---|
| Vue d'ensemble du SDK | Le framework et le SDK loopback de la plateforme |
| Loaders et actions | Chargement des données, mutations, accès à la session |
| Déployer un site PRISM | Mettre l'application sur un domaine avec TLS automatique |