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 - createSSRApp
andvue/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.mts
at 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