Having created an example Blazor WebAssembly application, I deployed it to both an IIS and an Apache for testing purposes.
When publishing the application, it generated a folder "wwwroot" and a file "web.config":
The "wwwroot" folder contains the whole application:
When deploying to IIS, everything works fine.
What I'm currently struggling with is to deploy to Apache.
The "web.config" file contains two rewrite rules.
Rule 1:
<rule name="Serve subdir">
<match url=".*" />
<action type="Rewrite" url="wwwroot\{R:0}" />
</rule>
Rule 2:
<rule name="SPA fallback routing" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="wwwroot\" />
</rule>
I've tried several things to get at least rule 1 working with mod_rewrite, like e.g.:
RewriteEngine on
RewriteRule ^.*?$ /wwwroot [QSA]
But I either get 404 or endless redirects.
My question
How to convert above rule 1 and rule 2 to Apache mod_rewrite configurations?
Update 1
I do think this one is a valid replacement for rule 1:
RewriteEngine on
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) /wwwroot/$1 [L]
I've got it from this Super User answer.
Update 2
There is a Microsoft documentation on how to host on Apache but it is missing the rewrite parts.
Update 3
Based on the above Microsoft document, I was able to resolve it:
Do not put the "wwwroot" folder into the root folder of the Apache website.
Instead, place the content of the "wwwroot" folder directly into the root folder of the Apache website.
Do not put any mod_rewrite rules at all to the ".htaccess" file.
Add this directive to the ".htaccess" file:
ErrorDocument 404 /index.html
The complete, minimal ".htaccess" file for my test application looks like this:
ErrorDocument 404 /index.html
AddType application/wasm .wasm
AddType application/octet-stream .dll
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/octet-stream
AddOutputFilterByType DEFLATE application/wasm
<IfModule mod_setenvif.c>
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.0[678] no-gzip
BrowserMatch bMSIE !no-gzip !gzip-only-text/html
</IfModule>
</IfModule>
Update 4
Above example was for running the Blazor WebAssembly application directly from the root folder of an Apache website.
If you instead want to run it from a subfolder (let's say "/myappinfolder") some things have to be changed:
Move all files, including the ".htaccess" file, into the subfolder "myappinfolder".
Modify the
ErrorDocument
directive in the ".htaccess" file to:ErrorDocument 404 /myappinfolder/index.html
Change the base href in the "index.html" file to:
<base href="/myappinfolder/" />
Update 5
Instead of using the ErrorDocument
Apache directive, another option is to use the FallbackResource
Apache directive instead:
FallbackResource /myappinfolder/index.html
The FallbackResource
has the advantage that it keeps the HTTP method (e.g. POST
or GET
) when forwarding the request to the configured URL ("/myappinfolder/index.html" in my example).
Whereas ErrorDocument
always forwards the request to the configured URL ("/myappinfolder/index.html" in my example) with a GET
HTTP method.
(Idea from this SO answer)