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