Authoring in TSX
Create an email definition with a portable input schema and named fixtures, then preview, check, and publish its exact source.
Install @samva/markup, @samva/vite, vite and effect in your template project.
Set jsx: "react-jsx" and jsxImportSource: "@samva/markup/email" in TypeScript configuration.
/** @jsxImportSource @samva/markup/email */
import { Schema } from "effect";
import { Email, Section } from "@samva/markup/email/components";
import { defineEmail } from "@samva/markup/template";
export default defineEmail({
id: "welcome",
schema: Schema.toStandardJSONSchemaV1(
Schema.Struct({ firstName: Schema.String, items: Schema.Array(Schema.String) }),
),
fixtures: { basic: { firstName: "Ada", items: ["Your first project"] } },
render: (input) => ({
subject: `Welcome, ${input.firstName}`,
preheader: "Your account is ready",
body: (
<Email>
<Section>
<h1>Welcome, {input.firstName}</h1>
{input.items.length > 0 && (
<ul>{input.items.map((item) => <li key={item}>{item}</li>)}</ul>
)}
</Section>
</Email>
),
}),
});Each template id is unique within the project and independent of the file name. Ids and fixture keys start with a letter, digit or underscore and continue with letters, digits, dots, underscores or hyphens. Imported helpers are ordinary modules and do not need exclusion markers.
import { defineConfig } from "vite";
import { samvaEditor } from "@samva/vite";
export default defineConfig({ plugins: [samvaEditor({ templatesDir: "emails" })] });Run vite to preview declared fixtures. Run samva templates check before building or publishing.
Commit the project dependencies and a supported lockfile: Bun text lockfile version 2 or npm
lockfile version 3. Hosted builds consume that locked graph. Commit and push the checked source,
then use samva templates publish --commit HEAD on a clean exact commit reachable from the fetched
origin default branch. Publishing creates an immutable receipt.
buildTemplates() from @samva/vite/build returns per-entry previews and actual fixture output.
The CLI build writes a version 2 JSON artifact. Imported assets require their real HTTPS serving
base for check/build; local export through exportEmailProject from @samva/vite/project can
instead write relative assets beside the generated pages.
Conditions and repetition
Use ordinary TypeScript conditions and array mapping against validated email inputs and preview each branch with named fixtures.
Responsive and dark styles
Author responsive and dark email styles while keeping baseline content usable and reviewing compatibility findings for target clients.