.htaccess with single page website

Solution 1:

assets are indeed static resources.

If your "assets" are client-side static resources such as CSS, JS and images then you can't block them in .htaccess as they need to be publicly accessible for the client-side HTML to be able to access. (?)

RewriteRule ^$ index.html/ [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.html/$1 [QSA,L]

This is passing the requested URL as additional pathname information (ie. path-info) to index.html, eg. Request /foo/bar and it will send the request to index.html/foo/bar. The issue here is that the default text/html handler does not accept path-info by default and will trigger a 404.

But Vue.JS may not require this as path-info anyway - it may simply "scan the URL" as you suggest. In which case, you can simplify the directives something like:

Options All -Indexes
DirectoryIndex index.html

RewriteEngine On

RewriteRule ^index\.html - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]

This is a more "standard" front-controller. The QSA flags are not required here.

This rewrites everything that does not map to a file or directory to index.html. The first RewriteRule is simply an optimisation to prevent the rewritten request to index.html being retested.

You don't need to explicitly rewrite the root request (ie. RewriteRule ^$ index.html/) since mod_dir will do this via an internal subrequest having specified DirectoryIndex index.html.

Solution 2:

Try this:

Alias "/download"  "/wherever/your/app/is/download/"
AliasMatch "/.*" "/wherever/your/app/is/index.html"

These directives will route everything but /download/* to the index.html file.

These have to be included in the VirtualHost config, not in the .htaccess file. Note that with the Alias directive, you have to use a full filesystem path, not the relative path under the webroot.

Also, as @MrWhite pointed out, you might want to explicitly enable the usage of PathInfo for a html page, like this:

<Files index.html>
    AcceptPathInfo On
</Files>