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
- 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
- Only the template syntax is used, and props are only used for hint completion
 - → Satori supports common CSS features
 - → Tailwindcss documentation
 
<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/
- 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
- ▲ Satori is an amazing library for generating SVG strings from pure HTML and CSS.
 - Unfortunately, it is built on top of React’s JSX and expects “React-elements-like objects”.
 - Thank an other library natemoo-re/satori-html can to generate the necessary VDOM object from a string of HTML.
 - 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 filevue - createSSRAppandvue/server-renderer: transform HTML string
 
Why developed
My Weekend Pilot Project
- 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.mtsat my build time rather than the edge Fn - 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.
 - 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
- nuxt-og-image – Nuxt or want to use edge Fn
 
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