> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# html.inject

- **Type:** `'head' | 'body' | boolean | Function`
- **Default:** `'head'`

Set the inject position of the `<script>` tag.

Can be set to the following values:

- `'head'`: The `<script>` tag will be injected inside the `<head>` tag.
- `'body'`: The `<script>` tag will be injected at the end of the `<body>` tag.
- `true`: Automatically choose the injection position based on [html.scriptLoading](/config/html/script-loading.md). If it is set to `'blocking'`, the tag will be injected into the `<body>` tag; otherwise, it will be injected into the `<head>` tag.
- `false`: `<script>` tags will not be injected.

## Default inject position

The `<script>` tag is inside the head tag by default:

```html
<html>
  <head>
    <title></title>
    <script defer src="/static/js/runtime-main.js"></script>
    <script defer src="/static/js/main.js"></script>
    <link href="/static/css/main.css" rel="stylesheet" />
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
```

## Inject into body

Add the following config to inject `<script>` into the `<body>` tag:

```ts title="rsbuild.config.ts"
export default {
  html: {
    inject: 'body',
  },
};
```

You will see that the script tag is generated at the end of the body tag:

```html
<html>
  <head>
    <title></title>
    <link href="/static/css/main.css" rel="stylesheet" />
  </head>
  <body>
    <div id="root"></div>
    <script defer src="/static/js/runtime-main.js"></script>
    <script defer src="/static/js/main.js"></script>
  </body>
</html>
```

## Function usage

- **Type:**

```ts
type InjectFunction = (context: {
  value: ScriptInject;
  entryName: string;
}) => ScriptInject | void | Promise<ScriptInject | void>;
```

When `html.inject` is of type Function, the function receives an object as its parameter, with the following properties:

- `value`: the default inject configuration of Rsbuild.
- `entryName`: the name of the current entry.

In the context of MPA (Multi-Page Application), you can set different `inject` behaviors based on the entry name:

```ts title="rsbuild.config.ts"
export default {
  html: {
    inject({ entryName }) {
      return entryName === 'foo' ? 'body' : 'head';
    },
  },
};
```

## Manual injection

When `html.inject` is set to `false`, Rsbuild will not inject tags into the HTML, and the tags defined in [html.tags](/config/html/tags.md) will not take effect.

At this time, you can access all the tags to be injected through the `htmlPlugin.tags` template parameter, and manually inject them into the specified position.

For example, insert the `<script>` tag generated by Rsbuild between `a.js` and `b.js`:

```html title="index.html"
<html>
  <head>
    <script src="https://example.com/a.js"></script>
    <%= htmlPlugin.tags.headTags %>
    <script src="https://example.com/b.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <%= htmlPlugin.tags.bodyTags %>
  </body>
</html>
```

## Version history

| Version | Changes                                            |
| ------- | -------------------------------------------------- |
| v2.0.8  | Added support for async functions in `html.inject` |
