Serve Single Page Applications as static files in Spring Cloud Gateway
The problem
I can't find straight forward documentation or tutorial on how to host a Single Page Application app in Spring Cloud Gateway or Spring Webflux.
Single Page Applications (SPAs) are static files generated by apps written in Angular, React or Vue. They work basically over a single index.html page, a bunch of javascript files and assets (such as css, images and fonts). These webpages "fake" the URL navigation by making javascript rewrite them in the browser bar as the user navigates through the app, even though the paths shown aren't really files or folders in the system.
The expected solution
I would like to know the best and recommended way to fully and easily serve Single Page Applications in a Spring Cloud Gateway environment as taught in this nginx for SPA tutorial.
It can be divided in 3 main steps:
-
Serving static files in the Gateway from the filesystem or the classpath.
-
When the SPA is served on the root path "/": requests to "/" should serve "/index.html" instead of throwing 404.
-
When the SPA is served on the root path "/": requests to paths that result in 404 not found and are not routed to other back-ends should serve "/index.html". We can also call this nginx's try_files functionality.
What I have found
1) For serving static files in Spring Cloud Gateway
I have found:
1.1) This solution for serving files in the project's classpath
1, 2, 3 for serving files in the classpath
1.2) This solution for serving files in an arbitraty folder in the filesystem
1, although not clear on how to point it to the filesystem, my tests found it can be done with something like this:
@Configuration
@EnableWebFlux
public class StaticPagesWebFluxConfig implements WebFluxConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/**")
.addResourceLocations("file:./static-pages/")
.setCacheControl(CacheControl.noCache());
}
}
Special attention to the "file:/.static-pages/
2) For serving index.html when "/" is requested
The following route can be configured in Spring Cloud Gateway:
spring:
cloud:
gateway:
routes:
- id: root
predicates:
- Path=/
uri: forward:/index.html
3) For serving index.html when 404 is about to be thrown
Here is where I am struggling to find a solution!!! HELP!
These examples are not enough to provide the expected behavior: 1, 2, 3.
Even though in 3 the author states it achieved the try_files nginx's functionality it is not true as it only solves the 2) step.
Here is an example of a nginx configuration file with the expected behavior:
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html =404;
}
}
The try_files tells nginx to execute:
- serve requested uri - if not found, then...
- serve the requested uri with a postpended / - if not found, then...
- serve the /index.html - if not found, then...
- serve the default 404 error page
There is no facility for serving a page instead of a 404. This is just a spring boot app, there may be something there.
Hello! By "there" you mean Spring Boot's documentation/source code?
Yup, I realized I used "there" way too many times in that sentence 🤣. But yes, something in spring boot. Probably something like https://www.baeldung.com/spring-webflux-errors you might be able to do what you want. See the global bits towards the end.
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.