—Editor
Let your users write WhatsApp templates inside your app, with the phone preview next to the form and Meta's review rules checked as they type. One component for React or Vue, themed with CSS variables.
$ npm i @talqui-oss/template-builder @talqui-oss/template-builder-react01Live demo
Use {{name}} for variables and *bold*, _italic_, ~strike~ for formatting.
02Frontend
Both components render the same markup from the same core, so the styles and the behavior match. The editor keeps placeholders and their examples in sync as people type.
React
import { useState } from "react";
import {
TemplateEditor,
TemplatePreview,
} from "@talqui-oss/template-builder-react";
import "@talqui-oss/template-builder/styles.css";
import "@talqui-oss/template-builder/editor.css";
export function TemplateForm({ initial }) {
const [template, setTemplate] = useState(initial);
return (
<>
<TemplateEditor template={template} onChange={setTemplate} />
<TemplatePreview template={template} />
</>
);
}Vue 3
<template>
<TemplateEditor v-model:template="template" />
<TemplatePreview :template="template" />
</template>
<script>
import {
TemplateEditor,
TemplatePreview,
} from "@talqui-oss/template-builder-vue";
import "@talqui-oss/template-builder/styles.css";
import "@talqui-oss/template-builder/editor.css";
export default {
name: "TemplateForm",
components: { TemplateEditor, TemplatePreview },
props: { initial: { type: Object, required: true } },
data() {
return { template: this.initial };
},
};
</script>03Theme
Every color, font and radius is a CSS custom property on .tb-editor. The playground uses the same component with a dark theme.
theme.css
.tb-editor {
--tb-editor-font: "Inter", sans-serif;
--tb-editor-accent: #7c3aed;
--tb-editor-surface: #ffffff;
--tb-editor-control: #fafafa;
--tb-editor-radius: 12px;
}04Backend
Validate again on the server and send the request the adapter builds. Your access token never reaches the browser.
api/templates.ts
import { validate, toRequests } from "@talqui-oss/template-builder";
import { meta } from "@talqui-oss/template-builder/adapters/meta";
// POST /templates: what the editor submits
export async function createTemplate(template) {
const { valid, issues } = validate(template);
if (!valid) return { status: 422, issues };
const [request] = toRequests(
template,
meta({ wabaId: process.env.WABA_ID, accessToken: process.env.META_TOKEN }),
);
const response = await fetch(request.url, {
method: request.method,
headers: request.headers,
body: JSON.stringify(request.body),
});
return { status: response.status, body: await response.json() };
}