Use Vue file to generate Open Graph SVG or PNG

x-satori

Use Vue files to generate SVG images by Satori. The image can be generated by running ESM script or CLI.

x-satori-demo.mp4

Getting Started

npm install -D x-satori
Using CLI
  • Dependency: Vue | Vite
<vue_file_path> --config <satori_config_path> [ --output <path> | --dev ] OPTIONS: -d|--dev Turn on Dev mode -t|--template <path> The Vue template file path -c|--config <path> The export satori configure file path -o|--output <path> Target output SVG path EXAMPLES: x-satori --config "./satori.js" --template "./Template.vue" --dev x-satori --config "./satori.js" --template "./Template.vue" x-satori --config "./satori.js" --template "./Template.vue" -o image.svg

Configure

  • Extends Satori options and add Vue file props option
import { defineSatoriConfig } from 'x-satori/vue' export default defineSatoriConfig({ // ... Satori options props: { // ...Vue SFC props options // title: "Hello world" }, })

Vue template file

<script setup lang="ts">
const props = defineProps({
  title: String,
})
</script>
<template>
  <div class="w-full h-full flex text-white bg-blue-500 items-center justify-center">
    <h1 :style="{ fontSize: '70px' }">
      {{ title }} ?
    </h1>
  </div>
</template>

Example: playground/

Using ESM script
  • Dependency: Vue
import { defineSatoriConfig, satoriVue } from 'x-satori/vue' function main() { const _DIRNAME = typeof __dirname !== 'undefined' ? __dirname : dirname(fileURLToPath(import.meta.url)) const _OUTPUT = resolve(_DIRNAME, './image/og.png') const templateStr = await readFile(resolve(_DIRNAME, './Template.vue'), 'utf8') const opt = defineSatoriConfig({ // ... Satori options props: { // ...Vue SFC props options // title: "Hello world" }, }) const strSVG = await satoriVue(opt, templateStr) console.log(strSVG) } main()

Example: examples/run-esm-script

npm run gen:svg
npm run gen:png

How it works

  1. Satori is an amazing library for generating SVG strings from pure HTML and CSS.
  2. Unfortunately, it is built on top of React’s JSX and expects “React-elements-like objects”.
  3. Thank an other library natemoo-re/satori-html can to generate the necessary VDOM object from a string of HTML.
  4. So the key is to convert the Vue SFC file to an HTML string, and here I used transform so that I could generate it via script (Only the template syntax is used)
    • @vue/compiler-sfc: to parse Vue SFC file
    • vue - createSSRApp and vue/server-renderer: transform HTML string

Why developed

My Weekend Pilot Project

  1. This processing logic, initially used in my Vite-SSG person website qbb.sh, I prefer to run the script to generate e.g tsx gen-og.mts at my build time rather than the edge Fn
  2. And personally, I think Vue SFC File would be better in expressing this SVG structure, but I only use the template syntax and props, and the css would use tailwindcss.
  3. I did a experiment this weekend, using Vite HRM to improve DX, and developed a CLI so that I could run command and generated the SVG directly.

I’m happy that I finally finished this series of experiments and results this weekend.

ESM script source: qbb.sh /node/og/main.mts

Related Links

FAQ

CJS support ?

Not supported, waiting for upstream library natemoo-re/ultrahtml

I did it step by step according to the documentation of Vue and Vite, if you are interested, PR welcome ?

LICENSE

MIT Copyright (c) 2023 Q.Ben Zheng

GitHub

View Github