page.mdx 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. import { pageMetadata } from "@/lib/page-metadata"
  2. export const metadata = pageMetadata("docs/api/image")
  3. # @json-render/image
  4. Image renderer. Turn JSON specs into SVG and PNG images using [Satori](https://github.com/vercel/satori).
  5. ## Install
  6. ```bash
  7. npm install @json-render/core @json-render/image
  8. ```
  9. For PNG output, also install the optional peer dependency:
  10. ```bash
  11. npm install @resvg/resvg-js
  12. ```
  13. See the [Image example](https://github.com/vercel-labs/json-render/tree/main/examples/image) for a full working example.
  14. ## schema
  15. The image element schema for image specs. Use with `defineCatalog` from core.
  16. ```typescript
  17. import { defineCatalog } from '@json-render/core';
  18. import { schema, standardComponentDefinitions } from '@json-render/image';
  19. const catalog = defineCatalog(schema, {
  20. components: standardComponentDefinitions,
  21. });
  22. ```
  23. ## Render Functions
  24. Server-side functions for producing image output. Both accept a spec and optional `RenderOptions`.
  25. ```typescript
  26. import { renderToSvg, renderToPng } from '@json-render/image/render';
  27. const svg = await renderToSvg(spec, { fonts });
  28. const png = await renderToPng(spec, { fonts });
  29. await writeFile('output.png', png);
  30. ```
  31. ### RenderOptions
  32. ```typescript
  33. interface RenderOptions {
  34. registry?: ComponentRegistry;
  35. includeStandard?: boolean; // default: true
  36. state?: Record<string, unknown>;
  37. fonts?: SatoriOptions['fonts'];
  38. width?: number;
  39. height?: number;
  40. }
  41. ```
  42. <table>
  43. <thead>
  44. <tr>
  45. <th>Option</th>
  46. <th>Type</th>
  47. <th>Default</th>
  48. <th>Description</th>
  49. </tr>
  50. </thead>
  51. <tbody>
  52. <tr>
  53. <td><code>fonts</code></td>
  54. <td><code>{"SatoriOptions['fonts']"}</code></td>
  55. <td><code>[]</code></td>
  56. <td>Font data for text rendering (required for meaningful output)</td>
  57. </tr>
  58. <tr>
  59. <td><code>width</code></td>
  60. <td><code>number</code></td>
  61. <td>Frame prop</td>
  62. <td>Override the output image width</td>
  63. </tr>
  64. <tr>
  65. <td><code>height</code></td>
  66. <td><code>number</code></td>
  67. <td>Frame prop</td>
  68. <td>Override the output image height</td>
  69. </tr>
  70. <tr>
  71. <td><code>registry</code></td>
  72. <td><code>{"Record<string, ComponentRenderer>"}</code></td>
  73. <td><code>{"{}"}</code></td>
  74. <td>Custom component map (merged with standard components)</td>
  75. </tr>
  76. <tr>
  77. <td><code>includeStandard</code></td>
  78. <td><code>boolean</code></td>
  79. <td><code>true</code></td>
  80. <td>Include built-in standard components</td>
  81. </tr>
  82. <tr>
  83. <td><code>state</code></td>
  84. <td><code>{"Record<string, unknown>"}</code></td>
  85. <td><code>{"{}"}</code></td>
  86. <td>Initial state for <code>$state</code> / <code>$cond</code> dynamic prop resolution</td>
  87. </tr>
  88. </tbody>
  89. </table>
  90. ## Standard Components
  91. ### Root
  92. #### Frame
  93. Root image container. Defines the output image dimensions and background. Must be the root element.
  94. ```typescript
  95. {
  96. width: number;
  97. height: number;
  98. backgroundColor: string | null;
  99. padding: number | null;
  100. display: "flex" | "none" | null;
  101. flexDirection: "row" | "column" | null;
  102. alignItems: "flex-start" | "center" | "flex-end" | "stretch" | null;
  103. justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | null;
  104. }
  105. ```
  106. ### Layout
  107. #### Box
  108. Generic container with padding, margin, background, border, and flex alignment. Supports absolute positioning.
  109. ```typescript
  110. {
  111. padding: number | null;
  112. paddingTop: number | null;
  113. paddingBottom: number | null;
  114. paddingLeft: number | null;
  115. paddingRight: number | null;
  116. margin: number | null;
  117. backgroundColor: string | null;
  118. borderWidth: number | null;
  119. borderColor: string | null;
  120. borderRadius: number | null;
  121. flex: number | null;
  122. width: number | string | null;
  123. height: number | string | null;
  124. alignItems: "flex-start" | "center" | "flex-end" | "stretch" | null;
  125. justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | null;
  126. flexDirection: "row" | "column" | null;
  127. position: "relative" | "absolute" | null;
  128. top: number | null;
  129. left: number | null;
  130. right: number | null;
  131. bottom: number | null;
  132. overflow: "visible" | "hidden" | null;
  133. }
  134. ```
  135. #### Row
  136. Horizontal flex layout with optional wrapping.
  137. ```typescript
  138. {
  139. gap: number | null;
  140. alignItems: "flex-start" | "center" | "flex-end" | "stretch" | null;
  141. justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | null;
  142. padding: number | null;
  143. flex: number | null;
  144. wrap: boolean | null;
  145. }
  146. ```
  147. #### Column
  148. Vertical flex layout.
  149. ```typescript
  150. {
  151. gap: number | null;
  152. alignItems: "flex-start" | "center" | "flex-end" | "stretch" | null;
  153. justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | null;
  154. padding: number | null;
  155. flex: number | null;
  156. }
  157. ```
  158. ### Content
  159. #### Heading
  160. Heading text at various levels. h1 is largest, h4 is smallest.
  161. ```typescript
  162. {
  163. text: string;
  164. level: "h1" | "h2" | "h3" | "h4" | null;
  165. color: string | null;
  166. align: "left" | "center" | "right" | null;
  167. letterSpacing: number | string | null;
  168. lineHeight: number | null;
  169. }
  170. ```
  171. #### Text
  172. Body text with configurable size, color, weight, and alignment.
  173. ```typescript
  174. {
  175. text: string;
  176. fontSize: number | null;
  177. color: string | null;
  178. align: "left" | "center" | "right" | null;
  179. fontWeight: "normal" | "bold" | null;
  180. fontStyle: "normal" | "italic" | null;
  181. lineHeight: number | null;
  182. letterSpacing: number | string | null;
  183. textDecoration: "none" | "underline" | "line-through" | null;
  184. }
  185. ```
  186. #### Image
  187. Image from a URL with optional dimensions and fit.
  188. ```typescript
  189. {
  190. src: string;
  191. width: number | null;
  192. height: number | null;
  193. borderRadius: number | null;
  194. objectFit: "contain" | "cover" | "fill" | "none" | null;
  195. }
  196. ```
  197. ### Decorative
  198. #### Divider
  199. Horizontal line separator.
  200. ```typescript
  201. {
  202. color: string | null;
  203. thickness: number | null;
  204. marginTop: number | null;
  205. marginBottom: number | null;
  206. }
  207. ```
  208. #### Spacer
  209. Empty vertical space.
  210. ```typescript
  211. {
  212. height: number | null;
  213. }
  214. ```
  215. ## Catalog Definitions
  216. Pre-built definitions for creating image catalogs:
  217. ```typescript
  218. import { standardComponentDefinitions } from '@json-render/image/catalog';
  219. import { defineCatalog } from '@json-render/core';
  220. import { schema } from '@json-render/image';
  221. const catalog = defineCatalog(schema, {
  222. components: {
  223. ...standardComponentDefinitions,
  224. // Add custom components
  225. },
  226. });
  227. ```
  228. ## Server-Safe Import
  229. Import schema and catalog definitions without pulling in React or Satori:
  230. ```typescript
  231. import { schema, standardComponentDefinitions } from '@json-render/image/server';
  232. ```
  233. ## Sub-path Exports
  234. <table>
  235. <thead>
  236. <tr>
  237. <th>Export</th>
  238. <th>Description</th>
  239. </tr>
  240. </thead>
  241. <tbody>
  242. <tr>
  243. <td><code>@json-render/image</code></td>
  244. <td>Full package: schema, renderer, components, render functions</td>
  245. </tr>
  246. <tr>
  247. <td><code>@json-render/image/server</code></td>
  248. <td>Schema and catalog definitions only (no React or Satori)</td>
  249. </tr>
  250. <tr>
  251. <td><code>@json-render/image/catalog</code></td>
  252. <td>Standard component definitions and types</td>
  253. </tr>
  254. <tr>
  255. <td><code>@json-render/image/render</code></td>
  256. <td>Server-side render functions only</td>
  257. </tr>
  258. </tbody>
  259. </table>
  260. ## Types
  261. <table>
  262. <thead>
  263. <tr>
  264. <th>Export</th>
  265. <th>Description</th>
  266. </tr>
  267. </thead>
  268. <tbody>
  269. <tr>
  270. <td><code>ImageSchema</code></td>
  271. <td>Schema type for image specs</td>
  272. </tr>
  273. <tr>
  274. <td><code>ImageSpec</code></td>
  275. <td>Spec type for image output</td>
  276. </tr>
  277. <tr>
  278. <td><code>RenderOptions</code></td>
  279. <td>Options for render functions</td>
  280. </tr>
  281. <tr>
  282. <td><code>ComponentRenderProps</code></td>
  283. <td>Props passed to component render functions</td>
  284. </tr>
  285. <tr>
  286. <td><code>ComponentRenderer</code></td>
  287. <td>Component render function type</td>
  288. </tr>
  289. <tr>
  290. <td><code>ComponentRegistry</code></td>
  291. <td>Map of component names to render functions</td>
  292. </tr>
  293. <tr>
  294. <td><code>StandardComponentDefinitions</code></td>
  295. <td>Type of the standard component definitions object</td>
  296. </tr>
  297. <tr>
  298. <td><code>StandardComponentProps{'<K>'}</code></td>
  299. <td>Inferred props type for a standard component by name</td>
  300. </tr>
  301. </tbody>
  302. </table>