master
 1---
 2type ReplaceOption =
 3  | {
 4      /**
 5       * The pattern to match in the HTML content.
 6       * It can be a string, a regular expression, or null.
 7       * - If null, the replacer function will be called with the entire HTML content,
 8       *   and the replaceValue will be used as the result.
 9       * - If a string or RegExp, it will be used to find matches in the HTML content.
10       */
11      pattern: string | RegExp | null;
12      replaceValue: string;
13    }
14  | {
15      pattern: string | RegExp;
16      // eslint-disable-next-line @typescript-eslint/no-explicit-any
17      replacer: (match: string, ...args: any[]) => string;
18    }
19  | {
20      pattern: null;
21      replacer: (match: string) => string | Promise<string>;
22    };
23
24export type Props = { option: ReplaceOption } | { options: ReplaceOption[] };
25
26const raw = await Astro.slots.render('default');
27
28const replace = async function (html: string, option: ReplaceOption): Promise<string> {
29  if (option.pattern === null) {
30    return 'replacer' in option ? await option.replacer(html) : option.replaceValue;
31  }
32  return 'replacer' in option
33    ? html.replaceAll(option.pattern, option.replacer)
34    : html.replaceAll(option.pattern, option.replaceValue);
35};
36
37let html: string | undefined = undefined;
38if ('options' in Astro.props) {
39  for (const option of Astro.props.options) {
40    html = await replace(html || raw, option);
41  }
42} else if ('option' in Astro.props) html = await replace(raw, Astro.props.option);
43else html = raw;
44---
45
46<Fragment set:html={html} />