Skip to content

Header and footer scripts

Arkazzae edited this page Oct 7, 2026 · 1 revision

Header and footer scripts adds your own HTML and JavaScript to every front-end page: a Google Tag Manager container, an analytics tag, a site verification meta tag or a chat widget. It never runs PHP. Only administrators who may post unfiltered HTML can change the code.

Snippet plugins that run PHP have been a direct way into sites. This module only prints the code you enter into the page; nothing of it runs on the server.

Module ID scripts
Default Off
Available Unless DISALLOW_UNFILTERED_HTML is set in wp-config.php. SafeHouse then shows "DISALLOW_UNFILTERED_HTML is set in wp-config.php, so nobody may add raw scripts."
WP-CLI None
Since 0.1.0

How it works

The three places

Setting Where the code is printed
In <head> Early in <head>, on the wp_head hook at priority 1.
After <body> Right after the opening <body> tag, on the wp_body_open hook at priority 1. Needs a theme that calls wp_body_open().
Before </body> At the end of the page, on the wp_footer hook at priority 99.

SafeHouse prints each place's code exactly as saved. It does not check, filter or escape it. Each place holds up to 20000 characters; longer code is cut off at 20000 characters when you save, without a warning.

The same code goes on every front-end page. There is no per-page or per-post-type targeting. To run a script on some pages only, put that condition in the script itself or in your tag manager.

Where the code does not appear

  • In wp-admin.
  • In feeds and in the embed views of your posts (the /embed/ addresses).
  • On the maintenance page of Maintenance mode, which is a page of its own without the theme.
  • After <body>, on a theme that does not call wp_body_open().
  • For logged-in users with manage_options, when Do not output for logged-in administrators is on. Editors and other logged-in users still get the code.

A place that is empty or holds only spaces and line breaks prints nothing.

Settings

On SafeHouse → Modules → Header and footer scripts, select Details.

Setting Default What it does
In <head> Empty "Printed early in <head>. Google Tag Manager, analytics, verification meta tags."
After <body> Empty "Needs a theme that calls wp_body_open() (all current themes do). GTM noscript iframe."
Before </body> Empty "Chat widgets, pixels and other scripts that can load last."
Do not output for logged-in administrators Off "Keeps your own visits out of analytics." Applies to users with manage_options.

Who can edit the code

The SafeHouse settings page needs manage_options. The three code fields also need unfiltered_html:

  • For a user without unfiltered_html, the three fields are grayed out, without an explanation. Saving the settings keeps the code that was there.
  • On multisite, WordPress gives unfiltered_html only to super admins, so a site administrator sees the fields grayed out.
  • With DISALLOW_UNFILTERED_HTML set to true in wp-config.php, WordPress gives unfiltered_html to nobody. SafeHouse then marks the module Unavailable and prints nothing. Code saved earlier stays in the settings. SHOUSE_IGNORE_OVERLAPS does not change this.

Add a tracking code

  1. Go to SafeHouse → Modules.
  2. Turn on Header and footer scripts and select Details.
  3. Paste each part of the code into the place your provider names. For Google Tag Manager, the <script> part goes into In <head> and the <noscript> part into After <body>.
  4. To keep your own visits out of the statistics, turn on Do not output for logged-in administrators.
  5. Select Save Changes.

Every save of SafeHouse settings clears the LiteSpeed page cache and the Cloudflare cache when those modules run, so cached pages pick up the code. Clear any other page cache yourself.

To check the result, open a page in a private window and view its source. With Do not output for logged-in administrators on, you do not see the code while logged in as an administrator.

Change history in the activity log

Every save that changes the code of one or more places writes a scripts_changed warning to the activity log, for example:

Front-end snippets changed: head, footer

The places are named head, body_open and footer. Like every activity log entry, it records the user who saved and their IP address. It also stores the SHA-256 hash of each changed place's code, not the code itself. The hashes sit in the entry's context in the {prefix}shouse_log table. Neither the Activity log panel nor wp shouse log shows them.

Changes are logged while the module is off too, because the fields can be edited either way.

What it stores

  • The code of the three places and the Do not output for logged-in administrators switch, in the option shouse_settings. Uninstalling SafeHouse deletes them.
  • scripts_changed entries in the activity log, kept for 90 days.

Limitations

  • SafeHouse prints the code without checking it. A broken snippet can break every front-end page.
  • No per-page targeting, no scheduling and no consent handling. The code runs on every page view; handle cookie consent in the script or in your consent tool.
  • HTML and JavaScript only. There is no PHP snippet support.
  • Code longer than 20000 characters per place is cut off without a warning.
  • Do not output for logged-in administrators skips users with manage_options only, not other roles.
  • Fields locked for a user without unfiltered_html show no reason.
  • Only the LiteSpeed page cache and Cloudflare cache modules are cleared when you save. Other page caches can keep serving pages without the change.

Related pages

Clone this wiki locally