How to Inject Custom HTML/JavaScript into Static Pages Using Apache Modifications


1 views

When working with static HTML sites on Apache servers, we often encounter situations where direct file modification isn't feasible - whether due to CMS limitations, deployment constraints, or maintainability concerns. The requirement to inject common elements (tracking pixels, ads, headers/footers) across all pages is particularly common in web development.

Apache provides several powerful modules for content injection:

# Using mod_substitute in httpd.conf
<Location />
    AddOutputFilterByType SUBSTITUTE text/html
    Substitute "s|</body>|<script src='/tracker.js'></script></body>|i"
</Location>

For more complex injections, combine multiple Apache modules:

# Combining mod_headers and mod_setenvif
<FilesMatch "\.(html|htm)$">
    Header set X-Injected "true"
    SetEnvIf Request_URI "^/special/" SPECIAL_PAGE
    Header add Link "</styles/injected.css>; rel=preload" env=!SPECIAL_PAGE
</FilesMatch>

For dynamic injection without modifying origin files:

<!-- In your HTML template -->
<esi:include src="/ads/banner.html"/>

# Apache configuration
LoadModule expires_module modules/mod_expires.so
LoadModule include_module modules/mod_include.so
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml

When working with proxied content, modify responses on-the-fly:

# Using mod_proxy_html
<Proxy *>
    ProxyHTMLEnable On
    ProxyHTMLURLMap /old-banner.js /new-tracker.js
    ProxyHTMLInsert "<div id='injected-footer'></div>" "<body>"
</Proxy>

Always test injection performance impact. For high-traffic sites, consider:

  • Cache injection results with mod_cache
  • Minify injected JavaScript/CSS
  • Use asynchronous loading for non-critical elements

When working with static HTML websites hosted on Apache, we often encounter situations where direct file modification isn't feasible. Common scenarios include:

  • CMS-generated static sites
  • Third-party provided content
  • Large legacy codebases

The most efficient way to handle this is through Apache's mod_substitute module. Unlike mod_proxy which isn't designed for content manipulation, mod_substitute provides powerful pattern-based substitution capabilities.


# Enable required modules
LoadModule filter_module modules/mod_filter.so
LoadModule substitute_module modules/mod_substitute.so

<Location "/">
    AddOutputFilterByType SUBSTITUTE text/html
    Substitute "s|</head>|<script src='/banner.js'></script></head>|i"
    Substitute "s|</body>|<img src='tracking.gif' style='display:none'></body>|i"
</Location>

For more complex scenarios, consider these alternatives:

Using mod_rewrite with PHP


RewriteEngine On
RewriteCond %{REQUEST_URI} \.html$
RewriteRule ^(.*)$ wrapper.php?file=$1 [L]

// wrapper.php content:
<?php
    $content = file_get_contents($_GET['file']);
    $content = str_replace('</body>', 'YOUR_CONTENT</body>', $content);
    echo $content;
?>

Edge Side Includes (ESI)

If you're using a reverse proxy like Varnish:


<esi:include src="/banner.html"/>

When implementing these solutions:

  • Benchmark server load with and without substitutions
  • Consider caching strategies for modified content
  • Measure latency impact on page delivery