Serving Your React App Through CDN
Serving your React application through a Content Delivery Network (CDN) can significantly enhance its performance and scalability. In this guide, we’ll walk through the steps to build and deploy your React app to a CDN, making it available for embedding in other applications. ( chatGPT 🤠)
We'll use the Tailwind CSS in this example because if we use raw CSS then we'll have to deploy the CSS file too on the CDN to use it. Tailwind is already available through CDN, so why not!!
So the overall idea is to build a child app and render that on your parent app. For this article, we'll build a weather app (child app) that will take user input and show the current weather of the entered location. and we'll bundle this child app deploy it on CDN and use it to render on a parent app. Easy-peasy!! 👼
Step 1: Create your React application
I'm using Vite instead of CRA (create-react-app) because of this. And bun instead od npm.
bun create vite weather --template react
Folder structure (I've deleted CSS files)
weather
├── dist
├── node_modules (library root)
├── public
├── src
│ ├── assets
│ ├── App.jsx
│ └── main.jsx
├── .eslintrc.cjs
├── .gitignore
├── bun.lockb
├── index.html
├── package.json
├── README.md
└── vite.config.js
main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
const renderApp = (containerId) => {
const rootElement = document.getElementById(containerId);
if (rootElement) {
ReactDOM.createRoot(rootElement).render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
}
};
// Export the render function to be used externally
if (typeof window !== 'undefined') {
window.WeathearComponent = renderApp;
}
// uncomment below line to render the app from this app
// renderApp('root')
export { App, renderApp };
App.jsx
import {useEffect, useState} from 'react'
import axios from 'axios'
function App() {
const [weather, setWeather] = useState({})
const [location, setLocation] = useState('india')
const [text, setText] = useState('Please enter the location')
const getData=async ()=>{
try {
let config = {
method: 'get',
maxBodyLength: Infinity,
url: `https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/${location}/today?unitGroup=us&include=current&key=HCQKD6HKWGTUT87A29L4KTT2U&contentType=json`,
headers: {}
};
const response = await axios.request(config);
setWeather(response.data)
}catch (e){
setText('Invalid location!')
setWeather({})
}
}
useEffect(() => {
getData();
}, [location]);
return (
<div id={"weather"} className={"m-2 p-4 w-max flex flex-col justify-center align-center border-2 text-center gap-4"} >
<p className={"bg-gradient-to-r from-blue-600 via-green-500 to-indigo-400 inline-block text-transparent bg-clip-text"}>
Hello from weather component!
</p>
<h2>
<input
className={'w-40 text-center rounded-md border-0 py-1.5 text-gray-900 ring-1 placeholder:text-gray-400 focus:ring-indigo-100'}
type="text"
value={location}
onChange={(e) => setLocation(e.target.value)}
placeholder="Enter location"
/>
</h2>
<p className={"bg-gradient-to-r from-blue-600 via-orange-500 to-yellow-400 inline-block text-transparent bg-clip-text"}>
{location ? weather?.currentConditions?.conditions || text : 'Please enter the location'}
</p>
</div>
)
}
export default App
Now, let's bundle this app using the below configurations.
vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
build: {
rollupOptions: {
input: './index.html',
output: {
entryFileNames: '[name].js',
chunkFileNames: '[name].js',
assetFileNames: '[name].[ext]'
}
}
},
publicDir: 'public',
root: '.',
base: './',
});
bun run build
Dist folder will be generated after running the above command

We need to use this index.js file in our parent application, and instead of deploying it on CDN and then using it, for testing, we can serve this js file from our local.
Follow these steps to serve this index.js file
#Open dist folder in your terminal and..
#Step 1:
bun add http-server
#Step 2:
http-server --cors -p 5173
Now, let's create the parent app.
bun create vite parent --template react
The parent app will also have the same folder structure. (In this app also I'm using Tailwind CSS so I've deleted the CSS files)
parent
├── dist
├── node_modules (library root)
├── public
├── src
│ ├── assets
│ ├── App.jsx
│ └── main.jsx
├── .eslintrc.cjs
├── .gitignore
├── bun.lockb
├── index.html
├── package.json
├── README.md
└── vite.config.js
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
<script src="https://cdn.tailwindcss.com"></script>
<script type="module" src="http://127.0.0.1:5173/index.js"></script>
</body>
</html>
Keep the main.jsx as it is.
App.jsx
function App() {
window.onload = function () {
window.WeathearComponent('weather')
}
return (
<>
<div className={"border flex flex-col justify-center items-center"}>
<p>I'm parent</p>
<div id={'weather'}>
</div>
</div>
</>
)
}
export default App
Now run this application
bun run dev
And Voilà ...

Find the GitHub repository here with both applications.
Since this is my early stage of blogging please let me know in the comments if you have any tips or suggestions on how I can improve my content.
Thank You..!!!!