Skip to content

Serve static content

Small amounts of static content can be served from a WordPress environment. A static file (e.g., *.html, *.txt ) can be added to a directory within an application’s GitHub repository. This method should be used sparingly for files that are small in size.

Static files added to an application’s GitHub repository are web-accessible at a URL with a corresponding path underneath /wp-content/. For example, a file added to a site’s /themes directory in the GitHub repository could be accessed at a URL similar to:
https://example.com/wp-content/themes/file.html

Note

If a static file is added to the root of the GitHub repository, it will not deploy as expected. The file must be added within one of the supplied directories in the WordPress codebase, usually within a site’s theme directory.

A custom URL path to access static files can be created by adding a rewrite rule, outlined below. This method is useful for serving common static files at custom URL paths including:

  • .well-known/apple-developer-merchantid-domain-association
  • .well-known/apple-app-site-association

Limitations

A subset of static file types can only be served from directory paths within /wp-content/uploads/wp-content/plugins/wp-content/themes, or /wp-content/images. Rewrite rules cannot be applied to serve static content with file extensions .css, .jpg.jpeg, .gif, .png, .swf, .ico at custom URL paths.

JavaScript resource files

Serving a JavaScript (JS) resource file from within an application’s wpcomvip GitHub repository has additional requirements:

  • The JS resource file must have a .js file extension.
  • The allowed characters in the JS file name are limited to: A–Z a–z _ -.

Root level requests for a JavaScript resource file are automatically routed to PHP if the file meets all of the above requirements and a rewrite rule has been added.

As an example, service workers are a common JavaScript resource file that must be available at a root level URL path. A service worker uses the Web Worker API to run JavaScript in a background thread. Because JavaScript is executed in a single thread, offloading resource-intensive tasks to a service worker, simulating a second thread, can speed up site performance and offer native-app-like features (such as in-browser push notifications). Service workers are becoming more common as Google has defined them as a key part of Progressive Web Apps.

This example file name and file path for a service worker meets all of the above requirements and can be routed automatically to PHP with an added rewrite rule:
https://example.com/service-worker.js

These example file paths and file names do not meet the requirements and therefore cannot route to PHP:

  • https://example.com/service-worker-123.js
  • https://example.com/service-worker-v1
  • https://example.com/subdir/service-worker.js

How to serve a static file with a rewrite rule

A static file in an application’s GitHub repository can be served from a custom URL path by adding a rewrite rule with the add_rewrite_rule() WordPress function. The first argument added to add_rewrite_rule() is a regular expression (regex) to match against the requested URL. Any characters added to this regex other than a-z A-Z 0-9 must be escaped with a backslash (\) in order for the rewrite rule to work as expected.

The steps in the example below explain how to serve an ads.txt static file at a custom path, but the instructions can be adapted to serve other static file types at custom URL paths.

The ads.txt specification is an IAB-approved text file for preventing unauthorized sales of inventory. To work as expected, the ads.txt file must be located on a site’s root domain. Though it is possible to configure an ads.txt with a plugin (e.g., Ads.txt Manager), the instructions below explain how to accomplish this without a plugin and with code instead.

  1. Commit the ads.txt file to the application’s /themes directory.
  2. Add a rewrite rule for the file to be accessible at a custom URL.
    In this code example, a rewrite rule is added for the ads.txt file to be served at the site’s root domain: https://example.com/ads.txt
/themes/my-active-theme/functions.php
/**
 * Register the rewrite rule for /ads.txt request.
 */
function my_theme_adstxt_rewrite() {
    add_rewrite_rule( '^ads\.txt$', 'index.php?my_theme_adstxt=true', 'top' );
}
add_action( 'init', 'my_theme_adstxt_rewrite', 10 );
 
/**
 * Filter the list of public query vars in order to allow the WP::parse_request
 * to register the query variable.
 *
 * @param array $public_query_vars The array of public query variables.
 *
 * @return array
 */
function my_theme_adstxt_query_var( $public_query_vars ) {
    $public_query_vars[] = 'my_theme_adstxt';
    return $public_query_vars;
}
add_filter( 'query_vars', 'my_theme_adstxt_query_var', 10, 1 );
 
/**
 * Hook the parse_request action and serve the ads.txt when custom query variable is set to 'true'.
 *
 * @param WP $wp Current WordPress environment instance
 */
function my_theme_adstxt_request( $wp ) {
    if ( isset( $wp->query_vars['my_theme_adstxt'] ) && 'true' === $wp->query_vars['my_theme_adstxt'] ) {
        /*
         * Set proper content-type as per specifications provided by these guides :
         * https://iabtechlab.com/ads-txt/
         *
         * The HTTP Content-type should be ‘text/plain’, and all other Content-types should be treated
         * as an error and the content ignored.
         */
        header( 'Content-Type: text/plain' );
 
        // The code expects an existing ads.txt file in the root of your active theme.
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The ads.txt spec requires and expects plain text, so no escaping needed.
        echo file_get_contents( get_stylesheet_directory() . '/ads.txt' );
        exit;
    }
}
add_action( 'parse_request', 'my_theme_adstxt_request', 10, 1 );

How to flush rewrite rules

After a new rewrite rule has been added, merged, and deployed, it will not work as expected until rewrite rules have been flushed. Rewrite rules are not flushed when code is deployed to an environment; they must be flushed manually.

To flush rewrite rules:

  1. Log in to the site’s WordPress Admin dashboard.
  2. In the lefthand navigation of the WP Admin, hover over the VIP menu item.
  3. Select Rewrite Rules from the fly-out menu.
  4. Select the “Flush Rules” button at the upper right of the Rewrite Rules dashboard.

As an alternative, rewrite rules can also be flushed by using VIP-CLI to run the WP-CLI command wp rewrite flush.

Last updated: January 15, 2024

Relevant to

  • WordPress