I have a custom rewrite rule which rewrites /wp-content/themes/my-theme/manifest.json to /index.php?manifest=true. This generates some JSON code for progressive web app functionality, and generally works great.

On a multisite install, however, the manifest loads correctly, but still sends a 404 header. I verified that this specific theme does work fine with a normal WordPress site, but in a multisite install, it always seems to send the 404 header.

enter image description here

Some notes:

  • I’ve tried using status_header(200), and header("HTTP/1.1 200 OK") manually, but neither of those make a difference
  • I’ve tried setting $wp->is_404 to false, but that does nothing
  • I’ve flushed the permalinks, but that does nothing

Rewrite Rule PHP:

// set up rewirte rules for PWA functionality
function fvpd_pwa_rewrite_rules() {
    add_rewrite_endpoint("manifest", EP_NONE);
    add_rewrite_rule(substr(parse_url(get_template_directory_uri(), PHP_URL_PATH), 1) . "/manifest\.json$", "index.php?manifest=true", "top");
}
add_action("init", "fvpd_pwa_rewrite_rules");

manifest.json PHP:

// construct a manifest when the user visits {theme_folder}/manifest.json
function fvpd_construct_manifest() {
    if (get_query_var("manifest")) {
        header("Content-Type: application/json");

        $name             = fvpd_get_field("full_name", "pwa");
        $short_name       = fvpd_get_field("short_name", "pwa");
        $background_color = fvpd_get_field("background_color", "pwa");
        $theme_color      = fvpd_get_field("theme_color", "pwa");

        $manifest = array(
            "start_url"        => "https://wordpress.stackexchange.com/",
            "display"          => "standalone",
            "name"             => $name ? $name : "Fox Valley Park District - DEV",
            "short_name"       => $short_name ? $short_name : "FVPD",
            "background_color" => $background_color ? $background_color : "#E58F1A",
            "theme_color"      => $theme_color ? $theme_color : "#E58F1A",
            "icons"            => array(
                array(
                    "src"   => get_theme_file_uri("assets/media/android/splash-icon-512x512.png"),
                    "type"  => "image/png",
                    "sizes" => "512x512",
                ),
                array(
                    "src"   => get_theme_file_uri("assets/media/android/launcher-icon-192x192.png"),
                    "type"  => "image/png",
                    "sizes" => "192x192",
                ),
                array(
                    "src"   => get_theme_file_uri("assets/media/android/launcher-icon-144x144.png"),
                    "type"  => "image/png",
                    "sizes" => "144x144",
                ),
                array(
                    "src"   => get_theme_file_uri("assets/media/android/launcher-icon-96x96.png"),
                    "type"  => "image/png",
                    "sizes" => "96x96",
                ),
                array(
                    "src"   => get_theme_file_uri("assets/media/android/launcher-icon-72x72.png"),
                    "type"  => "image/png",
                    "sizes" => "72x72",
                ),
                array(
                    "src"   => get_theme_file_uri("assets/media/android/launcher-icon-48x48.png"),
                    "type"  => "image/png",
                    "sizes" => "48x48",
                ),
            ),
        );

        echo json_encode($manifest); exit;
    }
}
add_action("wp", "fvpd_construct_manifest");

URL in questions:

https://www.foxvalleyparkdistrict.org/wp-content/themes/fox-valley-park-district/manifest.json

This does not affect my other custom rewrite, which points /offline/ to load a custom template.

https://www.foxvalleyparkdistrict.org/offline/

Why is the 404 header being sent, and how can I fix it?


UPDATE 1:

I tried some of the advice below, but to no avail. I do have some additional information that may help, however. I tested changing the rewrite to /manifest.json instead of /wp-content/themes/my-theme/manifest.json, and that actually worked! This gave me an idea, and so I tried the following:

| URL                        | Status | Folder Exists | WordPress Folder |
|:--------------------------:|:------:|:-------------:|:----------------:|
| /manifest.json             | 200    | N/A           | N/A              |
| /wp-admin/manifest.json    | 404    | true          | true             |
| /wp-content/manifest.json  | 404    | true          | true             |
| /wp-includes/manifest.json | 404    | true          | true             |
| /cgi-bin/manifest.json     | 403    | true          | false            |
| /custom/manifest.json      | 200    | false         | false            |
| /custom/manifest.json      | 200    | true          | false            |

It seems that if the rewrite is returning a 404 header only when set to an existing WordPress folder. My suspicion is that the rewrite engine is partially ignoring rules to /wp-* folders.

I may end up just keeping the rewrite at /manifest.json, but that creatures a problem if in the future we where to set up additional sites like https://example.com/second-site/, although that could probably be fixed by rewriting to the WordPress root instead of the server root.

UPDATE 2: .htaccess contents is visible here: https://gist.github.com/JacobDB/1531b75c8b8c79117516019225bb7732

4 Answers
4

Basically, you are doing one thing wrong, which is actually having a file named manifest.json inside /wp-content/themes/your-theme.

So, first, delete your file /wp-content/themes/your-theme/manifest.json.

Then, in your functions.php file you can have your rewrite rule as:

function fvpd_pwa_rewrite_rules() {
    add_rewrite_endpoint( "manifest", EP_NONE );
    add_rewrite_rule( substr( parse_url( get_template_directory_uri(), PHP_URL_PATH ), 1 ) . "/manifest.json/?$", "index.php?manifest=true", "top" );
}

add_action( "init", "fvpd_pwa_rewrite_rules" );

And your json content as:

// construct a manifest when the user visits {theme_folder}/manifest.json
function fvpd_construct_manifest() {
    if ( get_query_var( "manifest" ) ) {
        $name             = fvpd_get_field( "full_name", "pwa" );
        $short_name       = fvpd_get_field( "short_name", "pwa" );
        $background_color = fvpd_get_field( "background_color", "pwa" );
        $theme_color      = fvpd_get_field( "theme_color", "pwa" );

        $manifest = array(
            "start_url"        => "https://wordpress.stackexchange.com/",
            "display"          => "standalone",
            "name"             => $name ? $name : "Fox Valley Park District - DEV",
            "short_name"       => $short_name ? $short_name : "FVPD",
            "background_color" => $background_color ? $background_color : "#E58F1A",
            "theme_color"      => $theme_color ? $theme_color : "#E58F1A",
            "icons"            => array(
                array(
                    "src"   => get_theme_file_uri( "assets/media/android/splash-icon-512x512.png" ),
                    "type"  => "image/png",
                    "sizes" => "512x512",
                ),
                array(
                    "src"   => get_theme_file_uri( "assets/media/android/launcher-icon-192x192.png" ),
                    "type"  => "image/png",
                    "sizes" => "192x192",
                ),
                array(
                    "src"   => get_theme_file_uri( "assets/media/android/launcher-icon-144x144.png" ),
                    "type"  => "image/png",
                    "sizes" => "144x144",
                ),
                array(
                    "src"   => get_theme_file_uri( "assets/media/android/launcher-icon-96x96.png" ),
                    "type"  => "image/png",
                    "sizes" => "96x96",
                ),
                array(
                    "src"   => get_theme_file_uri( "assets/media/android/launcher-icon-72x72.png" ),
                    "type"  => "image/png",
                    "sizes" => "72x72",
                ),
                array(
                    "src"   => get_theme_file_uri( "assets/media/android/launcher-icon-48x48.png" ),
                    "type"  => "image/png",
                    "sizes" => "48x48",
                ),
            ),
        );

        wp_send_json( $manifest );
    }
}

add_action( "wp", "fvpd_construct_manifest" );

Notice the usage of the WordPress function wp_send_json() which handles for you necessary headers, json converting, etc.

Make sure you flush your permalinks and test the URL which will be something like http://localhost/wp-content/themes/your-theme/manifest.json.

If the above still doesn’t solve your issue it means you are also having trouble setting your web server correctly, NGINX or APACHE, following WordPress standards.

Leave a Reply

Your email address will not be published. Required fields are marked *