<commit_before>---
title: Customizing html.js
---

Gatsby uses a React component to server render the `<head>` and other parts of
the HTML outside of the core Gatsby application. Gatsby also sets a default value for the `<noscript>` tag there.

Most sites should use the default `html.js` shipped with Gatsby. But if you need
to customize your site's html.js, copy the default one into your source
tree by running:

```shell
cp .cache/default-html.js src/html.js
```

And then make modifications as needed.

If you need to insert custom html into the `<head>` or `<footer>` of each page on your site, you can use `html.js`.

## Required props

Note: the various props that are rendered into pages _are_ required e.g.
`headComponents`, `preBodyComponents`, `body`, and `postBodyComponents`.

## Inserting html into the `<head>`

Anything you render in the `html.js` component will _not_ be made "live" in
the client like other components. If you want to dynamically update your
`<head>` we recommend using
[React Helmet](/packages/gatsby-plugin-react-helmet/)

## Inserting html into the `<footer>`

If you want to insert custom html into the footer, html.js is the preferred way of doing this. If you're writing a plugin, consider using the `setPostBodyComponents` prop in the [Gatsby SSR API](/docs/ssr-apis/).

## Target container

If you see this error: `Uncaught Error: _registerComponent(...): Target container is not a DOM element.` it means your `html.js` is missing the required
"target container". Inside your `<body>` you must have a div with an id of
`___gatsby` like:

```jsx:title=src/html.js
<div
  key={`body`}
  id="___gatsby"
  dangerouslySetInnerHTML={{ __html: this.props.body }}
/>
```<commit_msg>docs(gatsby): html.js docs for themes (#19211)<commit_after>---
title: Customizing html.js
---

Gatsby uses a React component to server render the `<head>` and other parts of
the HTML outside of the core Gatsby application. Gatsby also sets a default value for the `<noscript>` tag there.

Most sites should use the default `html.js` shipped with Gatsby. But if you need
to customize your site's html.js, copy the default one into your source
tree by running:

```shell
cp .cache/default-html.js src/html.js
```

And then make modifications as needed.

If you need to insert custom html into the `<head>` or `<footer>` of each page on your site, you can use `html.js`.

> Customizing `html.js` is a workaround solution for when the use of the appropriate APIs is not available in `gatsby-ssr.js`. Consider using [`onRenderBody`](/docs/ssr-apis/#onRenderBody) or [`onPreRenderHTML`](/docs/ssr-apis/#onPreRenderHTML) instead of the method above.
> As a further consideration, customizing `html.js` is not supported within a Gatsby Theme. Use the API methods mentioned instead.

## Required props

Note: the various props that are rendered into pages _are_ required e.g.
`headComponents`, `preBodyComponents`, `body`, and `postBodyComponents`.

## Inserting html into the `<head>`

Anything you render in the `html.js` component will _not_ be made "live" in
the client like other components. If you want to dynamically update your
`<head>` we recommend using
[React Helmet](/packages/gatsby-plugin-react-helmet/)

## Inserting html into the `<footer>`

If you want to insert custom html into the footer, html.js is the preferred way of doing this. If you're writing a plugin, consider using the `setPostBodyComponents` prop in the [Gatsby SSR API](/docs/ssr-apis/).

## Target container

If you see this error: `Uncaught Error: _registerComponent(...): Target container is not a DOM element.` it means your `html.js` is missing the required
"target container". Inside your `<body>` you must have a div with an id of
`___gatsby` like:

```jsx:title=src/html.js
<div
  key={`body`}
  id="___gatsby"
  dangerouslySetInnerHTML={{ __html: this.props.body }}
/>
```
{'fraction_non_alphanumeric': 0.10224632068164213, 'fraction_numerical': 0.0012909888974954814, 'mean_word_length': 4.471751412429379, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5596146', 'n_tokens_mistral': 1177, 'n_tokens_neox': 1134, 'n_words': 531}