how to prefer static page if it exists over wordpress page

There are two issues here:

  1. Sending the request to /foo/page-x.html if it exists.
  2. Overriding the relative URL-paths to your static resources.

Normally, when rewriting the URL in this way (to different path depths) you should not be using relative URL-paths to your static resources, since the browser naturally resolves this relative to the URL-path displayed in the browser (this is not a file-path). However, if we know what URL-path is being requested and what file-path it should correspond to (as we appear to know in this case) then we can potentially override/correct this with additional rewrite(s) in .htaccess. If the same relative URL-path is used from different URLs then this becomes increasingly difficult to resolve as you would need to hardcode each possibility. Normally you should be using root-relative (or absolute) URL-paths to static resources to avoid this conflict/ambiguity.

The “problem” with the relative URL-path is that when requesting /lp/<page-name>/, a relative URL-path of the form ./public/page-x.js is resolved as /lp/<page-name>/public/page-x.js by the browser. So we need to rewrite this to /foo/public/page-x.js.

These rules need to go near the top of your .htaccess file located at /vhost/mysite/www/.htaccess (which I assume is the document root). Importantly, this needs to go before the WordPress code block (ie. before # BEGIN WordPress).

# 1. Rewrite "/lp/<page-name>/" to "/foo/<page-name>.html" if it exists
RewriteCond %{DOCUMENT_ROOT}/foo/$1.html -f
RewriteRule ^lp/([\w-]+)/$ /foo/$1.html [L]

# 2. Rewrite "relative" static resources
RewriteCond %{DOCUMENT_ROOT}/foo/$1 -f
RewriteRule ^lp/[\w-]+/([\w/-]+\.\w{2,5})$ /foo/$1 [L]

As denoted by the subpattern [\w-]+, I’m assuming <page-name> can consist of just the characters a-z, A-Z, 0-9, _ (underscore) and - (hyphen).

UPDATE: I’ve removed public/ from the RewriteRule pattern and included a slash (/) in the character class so to match any relative URL-path. It is advisable to keep the \.\w{2,5} part in order to avoid matching “too much”. We only want to match actual file requests (that contain a file extension), not literally anything.