# Combine heads (combine_heads)

Merges multiple head elements. How the mod_pagespeed combine_heads filter works, when to use it, its risks and the Apache, nginx and IIS directives.

Canonical URL: https://modpagespeed.com/docs/filters/combine_heads/

- Category: HTML
- CoreFilters: No
- OptimizeForBandwidth: No
- Risk: Generally safe

`combine_heads` folds extra `<head>` elements into the first one. When the module's HTML parse closes a second or later `<head>`, the contents of that element move into the first head and the emptied element disappears, so the served document carries exactly one head with everything in it. Not a core filter; enable it by name.

## How it works

Live demo: [combine_heads](https://modpagespeed.com/examples/combine_heads/).

### When it helps and when it does not

It helps on pages assembled from fragments that each ship a complete document skeleton: server-side includes that embed whole HTML files, portal or search pages that splice in results blocks with their own `<head>`, scraped or migrated content pasted with its original head. A browser's own parser discards the stray `<head>` tags and keeps the content, so such pages mostly render by accident; the merged output is predictable and gives the module's head-injecting filters one place to work. On a normal page with a single head the filter changes nothing.

### How it decides

The first `<head>` in the document is the survivor. Each later `</head>` moves its children into that first head, in document order. The merge cannot cross a flush boundary: when the server streams the page in chunks, heads that close in a later chunk than the first head stay as they are, because content already flushed to the browser cannot be restructured. The filter shares its implementation with [`add_head`](https://modpagespeed.com/docs/html-filters/#add_head): the same pass that inserts a missing `<head>` performs the merge, so enabling `combine_heads` also brings `add_head`'s behavior of inserting a head into documents that have none.

## When to use it

- Not in CoreFilters: it runs only when you enable it by name.
- Risk rating on these docs: **Generally safe**.

## Risks

- Content ordering inside the merged head follows the fragments, not any intent the fragments had; a fragment whose styles or scripts assumed their original position relative to other elements should be checked after enabling.

- Verify with the `X-Mod-Pagespeed` response header and a `?PageSpeedFilters=-combine_heads` comparison; [Is it working?](https://modpagespeed.com/docs/is-it-working/) has the steps.

## Configuration

Enable it in the module configuration, at server, virtual-host or location scope:

**Apache**

```apache
ModPagespeedEnableFilters combine_heads
```

**nginx**

```nginx
pagespeed EnableFilters combine_heads;
```

**IIS (pagespeed.config)**

```text
pagespeed EnableFilters combine_heads
```

```html
<!-- before: two fragments, each contributing its own head -->
<head>
  <title>Report</title>
</head>
...the first fragment's content...
<head>
  <link rel="stylesheet" href="/css/part2.css" />
</head>
...the second fragment's content...

<!-- after: one head, both fragments' head content in it -->
<head>
  <title>Report</title>
  <link rel="stylesheet" href="/css/part2.css" />
</head>
...the first fragment's content... ...the second fragment's content...
```

Scoping, `ForbidFilters` and the thresholds filters read: [Choosing filters](https://modpagespeed.com/docs/filter-selection/).

## Live example

See the before and after, with the source diff: [combine_heads example](https://modpagespeed.com/examples/combine_heads/).

## Frequently asked questions

**What does the combine_heads filter do?**

`combine_heads` folds extra `<head>` elements into the first one. When the module's HTML parse closes a second or later `<head>`, the contents of that element move into the first head and the emptied element disappears, so the served document carries exactly one head with everything in it. Not a core filter; enable it by name.

**Is combine_heads enabled by default?**

No. `combine_heads` is not in CoreFilters, the default RewriteLevel; it runs only when you enable it by name with `EnableFilters`.

**How do I enable combine_heads on Apache and nginx?**

Add `ModPagespeedEnableFilters combine_heads` on Apache or `pagespeed EnableFilters combine_heads;` on nginx. On IIS, add `pagespeed EnableFilters combine_heads` to pagespeed.config.

## Related filters

- [`add_base_tag`](https://modpagespeed.com/docs/filters/add_base_tag/): Add base tag
- [`add_head`](https://modpagespeed.com/docs/filters/add_head/): Add head
- [`add_ids`](https://modpagespeed.com/docs/filters/add_ids/): Add IDs
- [`add_instrumentation`](https://modpagespeed.com/docs/filters/add_instrumentation/): Add instrumentation
- [`collapse_whitespace`](https://modpagespeed.com/docs/filters/collapse_whitespace/): Collapse whitespace
- [`compute_statistics`](https://modpagespeed.com/docs/filters/compute_statistics/): Compute HTML statistics
- [`convert_meta_tags`](https://modpagespeed.com/docs/filters/convert_meta_tags/): Convert meta tags
- [`debug`](https://modpagespeed.com/docs/filters/debug/): Debug comments

This page is drawn from the [combine_heads entry on HTML filters](https://modpagespeed.com/docs/html-filters/#combine_heads). Every filter in one table: [PageSpeed filters](https://modpagespeed.com/docs/filters/).
