Skip to content

🌠 Using Astro or Vue file to generate cover, card, Open Graph ... image SVG, powered by Satori and Vite

License

Notifications You must be signed in to change notification settings

Zhengqbbb/x-satori

Folders and files

NameName
Last commit message
Last commit date

Latest commit

b11d7e4 Β· May 19, 2023

History

34 Commits
Mar 15, 2023
Mar 14, 2023
Mar 14, 2023
Mar 15, 2023
May 19, 2023
May 19, 2023
Apr 8, 2023
Mar 20, 2023
Mar 18, 2023
Mar 14, 2023
Mar 18, 2023
Mar 15, 2023
Mar 15, 2023
Mar 14, 2023
May 19, 2023
Mar 19, 2023
May 19, 2023
May 19, 2023
Mar 20, 2023
Mar 15, 2023

Repository files navigation

x-satori

version

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

Open in StackBlitz

Twitter/post

x-satori-demo.mp4


Local running example demo

npx degit Zhengqbbb/x-satori/playground <file_name>

cd <file_name>
pnpm install

# Development Model
pnpm dev

# [Generate] SVG
pnpm build
# or `pnpm gen:svg`

# [Generate] PNG
pnpm gen:png

Usage

npm install -D x-satori
Using CLI
  • Dependency: Vue | Vite
$ npx x-satori --help

SYNOPSIS:
    x-satori --template <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.

demo-img-1 demo-img-2
demo-img-3 demo-img-4
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