One of my Astro components that generates <head /> tags also generates an Open Graph image as a part of it's frontmatter. To be specific, I use the (satori)[https://github.com/vercel/satori] to generate an image based on the supplied props, and then write it to a file with common Node utilities.
Although the process of figuring out the correct paths during the building stage (I don't use SSR) was a hassle (maybe this part needs documentation and/or API improvement?), I managed to successfully do it, until I tried to create a dynamic Astro component page: I found out that the transpiled component executes twice, and the second time it executes without props (this is how I figured out the problem in the first place, the generated image had generic text as if no page-specific props were provided) it overwrites the original generated file. Here's an example of a frontmatter:
// /src/layouts/BaseHead/ImageTags.astro
import satori from 'satori';
import { join } from 'node:path';
import { writeFile } from 'node:fs/promises';
const { PROD, ROOT_DIR } = import.meta.env;
const { slug, text } = Astro.props; // <- 'text' is empty when Astro component is called the 2nd time
if (PROD) {
const path = join(ROOT_DIR, '/dist/og/', `${slug}.svg`);
const file = Buffer.from(await satori(/* ...options */));
await writeFile(path, file, { flag: 'wx' }); // <- This throws 'EEXIST: file already exists' error
}
How can I avoid generating the file twice? Maybe there is more idiomatic way to handle side-effects?