Private betav0.1.0
Docs
Format developer documentation

Vue

Format's Vue SDK provides bindings to our underlying document syntax

Installation

Use the Format CLI to install the @format.dev/vue package.

npx format add vue
pnpm dlx format add vue
yarn dlx format add vue
bun x format add vue

Example

An invoice document using the Vue SDK. The structural components are Document, Layout, Flow, and Stream; each takes props that map to the same attributes the document model uses. Props that hold numbers or arrays bind with :, and multi-word prop names use kebab-case (split-granularity).

An exported RenderProps<T> types the props. Format calls the document with the active data variant on data, and the generic fixes that variant's shape.

index.vue
<script setup lang="ts">
import { Document, Flow, Layout, type RenderProps, Stream } from '@format.dev/vue'
import './style.css'

interface Invoice {
	invoiceNo: string
	customerFullName: string
	customerType: string
	issueDate: string
	lineItems: LineItem[]
}

interface LineItem {
	name: string
	amount: number
}

const { data } = defineProps<RenderProps<Invoice>>()

const { invoiceNo, customerFullName, customerType, issueDate, lineItems } = data

const title = `Invoice #${invoiceNo}`
const subject = `Invoice for ${customerFullName}, issued on ${issueDate}`
</script>

<template>
	<Document :title="title" :subject="subject" author="Acme Co." :keywords="['Invoice', customerType]">
		<Layout id="invoice" :width="793.71" :height="1122.52">
			<header>{{ title }}</header>

			<Flow>
				<table>
					<thead>
						<tr><th>Item</th><th>Amount</th></tr>
					</thead>
					<tbody>
						<Stream>
							<tr v-for="(item, i) in lineItems" :key="i">
								<td>{{ item.name }}</td>
								<td>${{ item.amount.toLocaleString() }}</td>
							</tr>
						</Stream>
					</tbody>
				</table>
			</Flow>

			<Flow split-granularity="sentence">
				<!-- invoice terms: paragraphs flow across pages -->
			</Flow>
		</Layout>
	</Document>
</template>

The first Flow is scaffolded: the <table> header repeats on every page while the rows inside the Stream paginate. The second Flow is bare, so its <p> is the stream and splits at sentence boundaries when it overruns a page.

Documentation for every exported component lives in the Document model section. Each type page has a Vue tab showing the SDK form alongside React and HTML.

Was this page helpful?