Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serve Single Page Applications as static files in Spring Cloud Gateway #3365

Closed
tiagosmx opened this issue Apr 20, 2024 · 5 comments
Closed

Comments

@tiagosmx
Copy link

tiagosmx commented Apr 20, 2024

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:

  1. Serving static files in the Gateway from the filesystem or the classpath.

  2. When the SPA is served on the root path "/": requests to "/" should serve "/index.html" instead of throwing 404.

  3. 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:

  1. serve requested uri - if not found, then...
  2. serve the requested uri with a postpended / - if not found, then...
  3. serve the /index.html - if not found, then...
  4. serve the default 404 error page
@spencergibb
Copy link
Member

There is no facility for serving a page instead of a 404. This is just a spring boot app, there may be something there.

@tiagosmx
Copy link
Author

tiagosmx commented Apr 23, 2024

Hello! By "there" you mean Spring Boot's documentation/source code?

@spencergibb
Copy link
Member

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.

@spring-cloud-issues
Copy link

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.

@spring-cloud-issues
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants