Add React to a Website

You donā€™t have to build your whole website with React. Adding React to HTML doesnā€™t require installation, takes a minute, and lets you start writing interactive components right away.

You will learn

  • How to add React to an HTML page in one minute
  • What is the JSX syntax and how to quickly try it
  • How to set up a JSX preprocessor for production

Add React in one minute

React has been designed from the start for gradual adoption. Most websites arenā€™t (and donā€™t need to be) fully built with React. This guide shows how to add some ā€œsprinkles of interactivityā€ to an existing HTML page.

Try this out with your own website or an empty HTML file. All you need is an internet connection and a text editor like Notepad or VSCode. (Hereā€™s how to configure your editor for syntax highlighting!)

Step 1: Add a root HTML tag

First, open the HTML page you want to edit. Add an empty <div> tag to mark the spot where you want to display something with React. Give this <div> a unique id attribute value. For example:

<!-- ... existing HTML ... -->

<div id="like-button-root"></div>

<!-- ... existing HTML ... -->

Itā€™s called a ā€œrootā€ because itā€™s where the React tree will start. You can place a root HTML tag like this anywhere inside the <body> tag. Leave it empty because React will replace its contents with your React component.

You may have as many root HTML tags as you need on one page.

Step 2: Add the script tags

In the HTML page, right before the closing </body> tag, add three <script> tags for the following files:

Your HTML should now end like this:

    <!-- end of the page -->
    <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
    <script src="like-button.js"></script>
  </body>
</html>

Pitfall

Before deploying to a live website, make sure to replace development.js with production.min.js! Development builds of React provide more helpful error messages, but slow down your website a lot.

Step 3: Create a React component

Create a file called like-button.js next to your HTML page, add this code snippet, and save the file. This code defines a React component called LikeButton. (Learn more about making components in the Quick Start!)

'use strict';

function LikeButton() {
  const [liked, setLiked] = React.useState(false);

  if (liked) {
    return 'You liked this!';
  }

  return React.createElement(
    'button',
    {
      onClick: () => setLiked(true),
    },
    'Like'
  );
}

Step 4: Add your React component to the page

Lastly, add three lines to the bottom of like-button.js. These lines of code find the <div> you added to the HTML in the first step, create a React root, and then display the ā€œLikeā€ button React component inside of it:

const rootNode = document.getElementById('like-button-root');
const root = ReactDOM.createRoot(rootNode);
root.render(React.createElement(LikeButton));

Congratulations! You have just rendered your first React component to your website!

You can reuse components!

You might want to display React components in multiple places on the same HTML page. This is useful if React-powered parts of your page are separate from each other. You can do this by putting multiple root tags in your HTML and then rendering React components inside each of them with ReactDOM.createRoot(). For example:

  1. In index.html, add an additional container element <div id="another-root"></div>.
  2. In like-button.js, add three more lines at the end:
const anotherRootNode = document.getElementById('another-root');
const anotherRoot = ReactDOM.createRoot(anotherRootNode);
anotherRoot.render(React.createElement(LikeButton));

If you need to render the same component in many places, you can assign a CSS class instead of id to each root, and then find them all. Here is an example that displays three ā€œLikeā€ buttons and passes data to each.

Step 5: Minify JavaScript for production

Unminified JavaScript can significantly slow down page load times for your users. Before deploying your website to production, itā€™s a good idea to minify its scripts.

  • If you donā€™t have a minification step for your scripts, hereā€™s one way to set it up.
  • If you already minify your application scripts, your site will be production-ready if you ensure that the deployed HTML loads the versions of React ending in production.min.js like so:
<script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script>

Try React with JSX

The examples above rely on features that are natively supported by browsers. This is why like-button.js uses a JavaScript function call to tell React what to display:

return React.createElement('button', {onClick: () => setLiked(true)}, 'Like');

However, React also offers an option to use JSX, an HTML-like JavaScript syntax, instead:

return <button onClick={() => setLiked(true)}>Like</button>;

These two code snippets are equivalent. JSX is popular syntax for describing markup in JavaScript. Many people find it familiar and helpful for writing UI codeā€”both with React and with other libraries.

You can play with transforming HTML markup into JSX using this online converter.

Try JSX

The quickest way to try JSX is to add the Babel compiler as a <script> tag to the page. Put it before like-button.js, and then add type="text/babel" attribute to the <script> tag for like-button.js:

  <script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script src="like-button.js" type="text/babel"></script>
</body>

Now you can open like-button.js and replace

return React.createElement(
  'button',
  {
    onClick: () => setLiked(true),
  },
  'Like'
);

with the equivalent JSX code:

return (
  <button onClick={() => setLiked(true)}>
    Like
  </button>
);

It may feel a bit unusual at first to mix JS with markup, but it will grow on you! Check out Writing Markup in JSX for an introduction. Here is an example HTML file with JSX that you can download and play with.

Pitfall

The Babel <script> compiler is fine for learning and creating simple demos. However, it makes your website slow and isnā€™t suitable for production. When youā€™re ready to move forward, remove the Babel <script> tag and remove the type="text/babel" attribute youā€™ve added in this step. Instead, in the next section you will set up a JSX preprocessor to convert all your <script> tags from JSX to JS.

Add JSX to a project

Adding JSX to a project doesnā€™t require complicated tools like a bundler or a development server. Adding a JSX preprocessor is a lot like adding a CSS preprocessor.

Go to your project folder in the terminal, and paste these two commands (Be sure you have Node.js installed!):

  1. npm init -y (if it fails, hereā€™s a fix)
  2. npm install babel-cli@6 babel-preset-react-app@3

You only need npm to install the JSX preprocessor. You wonā€™t need it for anything else. Both React and the application code can stay as <script> tags with no changes.

Congratulations! You just added a production-ready JSX setup to your project.

Run the JSX Preprocessor

You can preprocess JSX so that every time you save a file with JSX in it, the transform will be re-run, converting the JSX file into a new, plain JavaScript file that the browser can understand. Hereā€™s how to set this up:

  1. Create a folder called src.
  2. In your terminal, run this command: npx babel --watch src --out-dir . --presets react-app/prod (Donā€™t wait for it to finish! This command starts an automated watcher for edits to JSX inside src.)
  3. Move your JSX-ified like-button.js (it should look like this!) to the new src folder.

The watcher will create a preprocessed like-button.js with the plain JavaScript code suitable for the browser.

Pitfall

If you see an error message saying ā€œYou have mistakenly installed the babel packageā€, you might have missed the previous step. Perform it in the same folder, and then try again.

The tool you just used is called Babel, and you can learn more about it from its documentation. In addition to JSX, it lets you use the most recent JavaScript syntax features without worrying about breaking older browsers.

If youā€™re getting comfortable with build tools and want them to do more for you, we cover some of the most popular and approachable toolchains here.

Deep Dive

React without JSX

Originally JSX was introduced to make writing components with React feel as familiar as writing HTML. Since then, the syntax has become widespread. However, there may be instances where you do not want to use or cannot use JSX. You have two options:

With JSX, you would write a component like so:

function Hello(props) {
  return <div>Hello {props.toWhat}</div>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Hello toWhat="World" />, );

With React.createElement(), you would write it like this:

function Hello(props) {
  return React.createElement('div', null, 'Hello ', props.toWhat);
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  React.createElement(Hello, { toWhat: 'World' }, null)
);

It accepts several arguments: React.createElement(component, props, ...children).

Hereā€™s how they work:

  1. A component, which can be a string representing an HTML element or a function component
  2. An object of any props you want to pass
  3. The rest are children the component might have, such as text strings or other elements

If you get tired of typing React.createElement(), one common pattern is to assign a shorthand:

const e = React.createElement;

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(e('div', null, 'Hello World'));

Then, if you prefer this style, it can be just as convenient as JSX.