Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use NGINX’s sub_filter directive to replace literal strings in an HTTP response body. It is provided by ngx_http_sub_module, which is not built into NGINX by default in source builds; first confirm that your installed binary includes the module. The filter is not an HTML-aware parser, so it changes matching text rather than interpreting markup.

What does NGINX sub_filter do?

NGINX describes ngx_http_sub_module as “a filter that modifies a response by replacing one specified string by another.” It operates on response content passing through NGINX, replacing matching strings in the body. The module’s directives are available in the http, server, and location contexts. See the official ngx_http_sub_module documentation.

Check that your NGINX build includes the module

The module is not built by default. For a source build, the NGINX build option is --with-http_sub_module, as listed in the NGINX configure documentation. Packaging differs, so do not assume a particular installed binary includes it. If NGINX reports an unknown sub_filter directive, verify module availability before changing the rule syntax.

How to configure sub_filter

The directive syntax is sub_filter string replacement;. This example follows the official documentation: it rewrites two kinds of links that begin with a local upstream address.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
location / {
    sub_filter '<a href="http://127.0.0.1:8080/' '<a href="https://$host/';
    sub_filter '<img src="http://127.0.0.1:8080/' '<img src="https://$host/';
    sub_filter_once on;
}

Adapt the strings to the exact response content and target host you intend to use. Matching is case-insensitive, and either the search string or replacement can contain variables. Because this is literal string replacement—not an HTML parser—it will not understand markup structure or rewrite text that does not match the configured string.

Choose whether to replace one or every occurrence

sub_filter_once controls how many times NGINX seeks each configured search string in a response. Its default is on, so a search string is sought once. Set it to off when the response may contain multiple occurrences that should all be replaced:

location / {
    sub_filter 'old.example' 'new.example';
    sub_filter_once off;
}

Set the response types to process

By default, sub_filter applies to responses with the text/html MIME type. Add other MIME types with sub_filter_types; use * to match any MIME type. For example, to include plain text as well as HTML:

location / {
    sub_filter 'old.example' 'new.example';
    sub_filter_types text/html text/plain;
}

Use the actual response type you need to modify. Applying the filter to every MIME type with * broadens its scope, so do that only when replacement is appropriate for all responses handled by that configuration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Understand rule inheritance

You can define multiple sub_filter rules at the same configuration level. Rules inherit from the previous level only when the current level defines no sub_filter directives. As a result, adding one local rule in a location can suppress the parent level’s set instead of supplementing it. When a location behaves differently than expected, check whether it defines its own rules and include every rule needed at that level.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Decide whether to preserve Last-Modified

When NGINX modifies response content, it removes the original Last-Modified header by default. The sub_filter_last_modified on; directive preserves that header to facilitate caching. Preserve it only when the header remains suitable for the modified response and your caching behavior; an upstream modification timestamp may not describe the filtered content itself.

Troubleshoot a rule that does not work

  • Unknown directive: confirm that the deployed NGINX binary includes ngx_http_sub_module; source builds need --with-http_sub_module.
  • Only one match changes: check whether sub_filter_once is still at its default, on; set it to off to seek repeated occurrences.
  • No change for a response type: by default, only text/html is processed. Add the response MIME type with sub_filter_types, or use * if every type should be covered.
  • A parent rule seems to disappear: inspect the current configuration level. Any local sub_filter directive means the parent rules are not inherited.
  • The text still does not match: compare the response body with the configured search string. The directive replaces literal strings; it does not parse HTML or infer equivalent markup.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.