Published on

String Replacements in Vite's index.html

Authors
  • Name
    Ripal & Zalak
    Twitter

String Replacements in Vite's index.html

When working with Vite, a fast and modern frontend build tool, you might encounter scenarios where you need to inject or replace strings dynamically in the index.html. This blog will guide you through various methods, from handling environment variables to custom solutions.

Problem: String Replacement in index.html

In tools like Vue CLI, string replacements in index.html are easily handled with placeholders like <%= BASE_URL %>. However, Vite's approach differs slightly. This guide will explore general solutions, including dynamic replacements and using environment variables, without requiring additional npm packages.


Solutions

1. Using Built-in Environment Variables

Vite supports environment variables out of the box. Here’s how you can use them:

Step 1: Define Variables

Create an .env file at the root of your project and define your variables:

VITE_APP_TITLE="My Vite App"

Step 2: Update index.html

In index.html, wrap the variable name in %:

<title>%VITE_APP_TITLE%</title>

Step 3: Build and Test

Vite will replace %VITE_APP_TITLE% with the value from the .env file during the build process.


2. Custom Plugin for HTML Transformations

If you require more flexibility, such as replacing custom placeholders, you can use a custom plugin.

Step 1: Create the Plugin

Add the following code in vite.config.js:

import { defineConfig } from 'vite'

const transformHtmlPlugin = (data) => ({
  name: 'transform-html',
  transformIndexHtml: {
    order: 'pre',
    handler(html) {
      return html.replace(/<%=\s*(\w+)\s*%>/g, (match, p1) => data[p1] || '')
    },
  },
})

export default defineConfig({
  plugins: [
    transformHtmlPlugin({
      title: 'My Custom Vite App',
      description: 'A blazing-fast frontend tool',
    }),
  ],
})

Step 2: Update index.html

Replace placeholders in your index.html:

<title><%= title %></title> <meta name="description" content="<%= description %>" />

This plugin will replace <%= title %> and <%= description %> with the specified values during the build.


3. Handling URI Errors in Environment Variables

When using environment variables in URLs (e.g., <link> tags), you may encounter URI errors. A workaround is to use unique delimiters, as shown below:

Step 1: Update index.html

<link href="_k_VITE_PUBLIC_URL_k_" rel="icon" />

Step 2: Configure the Plugin

export default defineConfig({
  plugins: [
    {
      name: 'html-transform',
      transformIndexHtml(html) {
        return html.replace(/_k_(.*?)_k_/g, (match, p1) => process.env[p1] || '')
      },
    },
  ],
})

Step 3: Define .env Variables

VITE_PUBLIC_URL="https://example.com"

The plugin replaces _k_VITE_PUBLIC_URL_k_ with the actual URL from the .env file.


4. Using vite-plugin-html

If you’re fine with using a package, vite-plugin-html is an excellent option.

Installation

npm install vite-plugin-html --save-dev

Configuration

import { defineConfig } from 'vite'
import { createHtmlPlugin } from 'vite-plugin-html'

export default defineConfig({
  plugins: [
    createHtmlPlugin({
      inject: {
        data: {
          title: 'My Vite App',
        },
      },
    }),
  ],
})

FAQs

1. Why doesn’t Vite use placeholders like Vue CLI?

Vite simplifies its approach by rebasing URLs automatically and using environment variables directly, reducing the need for specialized placeholders.

2. Can I use environment variables dynamically?

Yes. Use the loadEnv function in vite.config.js to load and pass variables dynamically.

import { defineConfig, loadEnv } from 'vite'

export default ({ mode }) => {
  const env = loadEnv(mode, process.cwd())
  return defineConfig({
    plugins: [transformHtmlPlugin({ ...env })],
  })
}

3. Is there a performance impact with custom plugins?

Minimal. Vite's plugin system is designed for efficiency, and transformations are applied during the build process only.