How to display a raw HTML page (bypassing WordPress theme, scripts, etc)

I’m a software engineer with a WordPress site with hundreds of pages, and it’s working very well.

There are certain cases, however, where I’d love to be able to code my own page with no interaction with / interference from the WordPress system (no themes, no styles, no javascript, etc) yet still have it located on that same subdomain.

How can I set to display an HTML file uploaded somewhere within /wp-content/?

And as a bonus, I’d love if it would also work with a PHP file (which would generate the HTML).

I’d like to do this without manually editing the .htaccess file.

Here is an example that comes close:

The LeadPages WordPress plugin seems to do a variation of what I’m hoping for. It allows a user to specify a “slug” (relative path, such as special-page) and what content to display there. But the content needs to be hosted on to use this plugin, obviously.

LeadPages plugin

What I’m hoping to do is host my own HTML file somewhere on my server (e.g. in a publicly-accessible folder such as /wp-content/) and then have a certain relative path point to it.

Look at this .htaccess file that I manually edited (and which works how I want):

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
Options +FollowSymLinks
DirectoryIndex /wp-content/raw/book-sale.html [L]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteRule ^thanks$ /wp-content/raw/book-opt-in-thank-you.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress

I would have loved to have been able to specify from within the WordPress admin that the site root (/) should show the contents of /wp-content/raw/book-sale.html, and /thanks should show /wp-content/raw/book-opt-in-thank-you.html (so that I wouldn’t need to go in an edit the .htaccess file directly.

Solutions Collecting From Web of "How to display a raw HTML page (bypassing WordPress theme, scripts, etc)"

You could create a page with the slug you want, and add a custom field that specifies the HTML path to output (in this example using either htmlfilepath or htmlurl as the metakey):


function maybe_direct_html_output() {
    if (is_singular()) {
        global $post;
        $htmlfilepath = get_post_meta($post->ID,'htmlfilepath',true);
        if ( ($htmlfilepath) && (file_exists($htmlfilepath)) ) {
            echo file_get_contents($htmlfilepath); exit;
        $htmlurl = get_post_meta($post->ID,'htmlurl',true);
        if ($htmlurl) {
            $html = wp_remote_get($html);
            if (!is_wp_error($html)) {echo $html['body']; exit;}

So no need for .htaccess when doing it this way… I just noticed you want to use wp-content so you could just use a relative path and simplify this to (using htmlfile metakey):


function maybe_direct_html_output() {
    if (is_singular()) {
        global $post;
        $htmlrelpath = get_post_meta($post->ID,'htmlfile',true);
        if (!$htmlrelpath) {return;}
        $htmlfilepath = WP_CONTENT_DIR.$htmlrelpath;
        if (!file_exists($htmlfilepath)) {return;}
        echo file_get_contents($htmlrelpath); exit;

Remembering that WP_CONTENT_DIR has no trailing slash so you would enter a relative path custom field value for the page such as /raw/book-sale.html

If you’re willing to create a child theme and put your PHP files in there, this approach is relatively clean. For each file, create a rewrite rule where you specify the path you want to use and the filename that should load. In the example below, /custom-path/ loads custom-file.php from the root of your child theme directory and /custom-path-2/ loads custom-file-2.php. Don’t forget to flush permalinks after adding rewrites.

 * Set up a rewrite for each path which should load a file.
function my_standalone_rewrites() {
    add_rewrite_rule( '^custom-path/?', 'index.php?standalone=custom-file', 'top' );
    add_rewrite_rule( '^custom-path-2/?', 'index.php?standalone=custom-file-2', 'top' );
add_action( 'init', 'my_standalone_rewrites' );

 * Make `standalone` available as a query var.
function my_query_vars( $vars ) {
  $vars[] = 'standalone';
  return $vars;
add_filter( 'query_vars', 'my_query_vars' );

 * If `standalone` is set when parsing the main query, load the standalone file.
function my_standalone_path( &$wp_query ) {
    if ( $wp_query->is_main_query() && get_query_var( 'standalone', false ) ) {
        // Load filename.php from your child theme root.
        get_template_part( get_query_var( 'standalone' ) );
add_action( 'parse_query', 'my_standalone_path' );