-
Scaffold a Vite project with the React template:
npm init vite my-react-project -- --template react
-
Install
vite-plugin-css-injected-by-jsto automatically inject the app's styles into the document<head>:cd my-react-project npm i -D vite-plugin-css-injected-by-js -
Configure Vite to use that plugin via
plugins; and to disable CSS code splitting viabuild.cssCodeSplit:// vite.config.js import { defineConfig } from 'vite' import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js' export default defineConfig({ plugins: [ cssInjectedByJsPlugin(), ], build: { cssCodeSplit: false, }, })
-
Configure Vite to build a single JavaScript file (i.e., the
main.jsxfile) viabuild.rollupOptions.input:// vite.config.js import { defineConfig } from 'vite' export default defineConfig({ build: { rollupOptions: { input: { app: './src/main.jsx', }, }, }, })
-
Configure Vite to specify the deployment target's base URL via
base:// vite.config.js import { defineConfig } from 'vite' export default defineConfig({ base: 'https://cdn.jsdelivr.net/gh/tony19-sandbox/vite-react-single-js-file/dist/', })
The base URL is ideally a CDN link for optimum load performance. For example, if the app files were hosted on GitHub at
https://github.com/tony19-sandbox/vite-react-single-js-file/tree/main/dist, the CDN link would behttps://cdn.jsdelivr.net/gh/tony19-sandbox/vite-react-single-js-file/dist/. -
Build the app:
cd my-react-project npm run buildThe build then produces a
distdirectory containing these files:dist/assets/app.d91c60c0.js dist/assets/logo.ecc203fb.svg
- In your blog page, insert a custom HTML block.
-
In the HTML block, add a
divwith an ID that matches the mounting point insrc/main.jsxfrom your app's original source (the default ID is"root").<div id="root">App loading...</div>
-
Add a
<script>that pulls in theapp.jsfile previously built. For example, if you've hosted the script on GitHub, you could use a CDN link like this:<script src="https://cdn.jsdelivr.net/gh/tony19-sandbox/vite-react-single-js-file/dist/assets/app.d91c60c0.js"></script>
The result looks like this:

