diff --git a/src/htmlEnvHook.ts b/src/htmlEnvHook.ts
new file mode 100644
index 0000000..2d44d82
--- /dev/null
+++ b/src/htmlEnvHook.ts
@@ -0,0 +1,48 @@
+import path from 'path'
+import { IndexHtmlTransformHook, normalizePath, ResolvedConfig, resolveEnvPrefix } from "vite"
+
+/**
+ * Support `%ENV_NAME%` syntax in html files
+ * @description Taken from vite/src/node/plugins/html.ts
+ * @link https://github.com/vitejs/vite/blob/c9e086d35ac35ee1c6d85d48369e8a67a2ba6bfe/packages/vite/src/node/plugins/html.ts#L1194
+ */
+export default function htmlEnvHook(config: ResolvedConfig): IndexHtmlTransformHook {
+ const pattern = /%(\S+?)%/g
+ const envPrefix = resolveEnvPrefix({ envPrefix: config.envPrefix })
+ const env: Record = { ...config.env }
+
+ // account for user env defines
+ for (const key in config.define) {
+ if (key.startsWith(`import.meta.env.`)) {
+ const val = config.define[key]
+ if (typeof val === 'string') {
+ try {
+ const parsed = JSON.parse(val)
+ env[key.slice(16)] = typeof parsed === 'string' ? parsed : val
+ } catch {
+ env[key.slice(16)] = val
+ }
+ } else {
+ env[key.slice(16)] = JSON.stringify(val)
+ }
+ }
+ }
+ return (html, ctx) => {
+ return html.replace(pattern, (text, key) => {
+ if (key in env) {
+ return env[key]
+ } else {
+ if (envPrefix.some((prefix) => key.startsWith(prefix))) {
+ const relativeHtml = normalizePath(
+ path.relative(config.root, ctx.filename),
+ )
+ config.logger.warn(
+ `(!) ${text} is not defined in env variables found in /${relativeHtml}. Is the variable mistyped?`,
+ )
+ }
+
+ return text
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index bae7437..0caeac2 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,6 +1,7 @@
-import { normalizePath, Plugin, ResolvedConfig } from 'vite';
+import { IndexHtmlTransformContext, normalizePath, Plugin, ResolvedConfig } from 'vite';
import path from 'path';
import fs from 'fs';
+import htmlEnvHook from './htmlEnvHook';
const attrNameExpr = '[a-z0-9_-]+';
const attrDataExpr = '[^"]*';
@@ -35,11 +36,14 @@ function injectHTML(pluginConfig?: InjectHTMLConfig): Plugin {
const fileList = new Set();
- async function renderSnippets(code: string, codePath: string) {
+ async function renderSnippets(code: string, ctx: IndexHtmlTransformContext) {
if (!config) {
return code;
}
+ const replaceHtmlEnv = htmlEnvHook(config);
+ code = (await replaceHtmlEnv(code, ctx)) as string;
+ const codePath = ctx.path;
const matches = code.matchAll(tagMatcher);
for (const match of matches) {
@@ -138,14 +142,10 @@ function injectHTML(pluginConfig?: InjectHTMLConfig): Plugin {
},
transformIndexHtml: {
enforce: 'pre',
- transform(html, ctx) {
- return renderSnippets(html, ctx.path);
- },
+ transform: renderSnippets,
// ^ Keeping for Vite below version 4.0.0
order: 'pre',
- handler(html, ctx) {
- return renderSnippets(html, ctx.path);
- },
+ handler: renderSnippets,
},
};
}