I use .netcore server side and vuejs 2.
I have generated html files for some routes of my vuejs, that I placed directly in the dist
folder:
I can access the html files with http://my-domain/en/home/index.html
, but calling http://my-domain/en/home
(without the index.html
) won't serve the html file. Instead, it will return the equivalent spa page.
What can I do to fix this? I want the server to return the html file if it exists in priority, otherwise return the normal spa website.
Here is part of my startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
// ...
// In production, the vue files will be served from this directory
services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/dist"; });
// ...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
// WebRootPath == null workaround. - from https://github.com/aspnet/Mvc/issues/6688
if (string.IsNullOrWhiteSpace(env.WebRootPath))
{
env.WebRootPath = Path.Combine(Directory.GetCurrentDirectory(), "ClientApp", "dist");
}
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
const int durationInSeconds = 60 * 60 * 24;
ctx.Context.Response.Headers[HeaderNames.CacheControl] =
"public,max-age=" + durationInSeconds;
}
});
app.UseSpaStaticFiles();
// ...
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseVueCli(npmScript: "serve", port: 8085);
}
});
}
EDIT: On top of @Phil 's response, I needed to provide a FileProvider because UseDefaultFiles
wasn't looking in the right folder:
app.UseDefaultFiles(new DefaultFilesOptions
{
FileProvider = new PhysicalFileProvider(env.WebRootPath) // important or it doesn't know where to look for
});
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
const int durationInSeconds = 60 * 60 * 24;
ctx.Context.Response.Headers[HeaderNames.CacheControl] =
"public,max-age=" + durationInSeconds;
},
FileProvider = new PhysicalFileProvider(env.WebRootPath) // same as UseDefaultFiles
});
You need to tell the server to use Default Files
With
UseDefaultFiles
, requests to a folder search for:default.htm
default.html
index.htm
index.html
app.UseDefaultFiles(); // this must come first
app.UseStaticFiles(...
This basically sets up an interceptor for requests on a folder (like your en/home
) and if it finds any of the above filenames, will rewrite the URL to folder/path/{FoundFilename}
.
If you want to avoid searches for anything other than index.html
, you can customise it
DefaultFilesOptions options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("index.html");
app.UseDefaultFiles(options);
Note the important information about ordering
Important
UseDefaultFiles
must be called beforeUseStaticFiles
to serve the default file.UseDefaultFiles
is a URL rewriter that doesn't actually serve the file. Enable Static File Middleware viaUseStaticFiles
to serve the file.