0

I am trying to serve a react frontend using actix server with the following service :

service(actix_files::Files::new("/app", "./react-front").index_file("./react-front/index.html")

And I have the following structure in react-front which is a react app build using npm run build:

react-front/
├── asset-manifest.json
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
├── precache-manifest.70429bbe96a34ea56e1cb1a6570602b0.js
├── robots.txt
├── service-worker.js
└── static
    ├── css
    │   ├── main.09af38e2.chunk.css
    │   └── main.09af38e2.chunk.css.map
    └── js
        ├── 1.e6893027.chunk.js
        ├── 1.e6893027.chunk.js.map
        ├── main.dc35c614.chunk.js
        ├── main.dc35c614.chunk.js.map
        ├── runtime~main.229c360f.js
        └── runtime~main.229c360f.js.map

http://localhost:5000/app Visiting /app I am greeted with this, where "Your React App loaded successfully" is the actual text in my index.html and the rest of the files as you can see from the network tab, gets a 404. I have placed this service before any of the routers in my App configuration, and were I to put this service after my routers I would just get this text and a 204 No Content. No more 404 errors for the react js scripts whatsoever.

This leads me to two questions:

1. What effects result from the order in which service for file resources is written for App builder?

2. How can one serve a complete folder such that the browser can obtain all the relevant css and js files necessary to display the react app?

Currently here's how I am dealing with it: I use the crate actix-web-static-files and static-files to embed the contents react-front folder into the final executable and then run it You can see that this works now. I want to achieve this without using these crates, just actix-files, if possible. Using the above crates react app loads fine Here's the working code for this :

HttpServer::new(move || {
        let generated = generate();
        App::new()
            .wrap(Cors::permissive())
            .route("/book", web::get().to(get_phonebook_handler))
            .route("/book/{id}", web::get().to(get_by_id))
            .route("/{name}", web::get().to(get_by_name))
            .route("/book/{id}", web::delete().to(delete_id))
            .route("/book", web::post().to(post_phonebook_handler))

            .route("/book/{id}", web::put().to(put_update))

            .service(ResourceFiles::new("/", generated))

    })
    .listen(tcp)?
    .run()
    .await
RequireKeys
  • 466
  • 4
  • 15
  • Can you see what URL exactly the app is trying to request which results in 404? Maybe the React app is trying to load from the absolute path `/static/css` instead of relative `./static/css`? – Dogbert Jun 11 '22 at 18:05
  • Maybe it was the way I wrote the service that caused the issue, changing to this : `.service(afs::Files::new("/", "./react-front").index_file("index.html"))` fixed it. One funny thing however this only works in firefox and chrome not on opera so I don't know whats up there. – RequireKeys Jun 12 '22 at 06:26
  • @Dogbert does this fix the issue because `index_file(...)` expects a file name rather than a file path to `index.html`? – RequireKeys Jun 12 '22 at 06:28
  • The first argument is the path where the files will be served and the second is the directory. So if you do `("/app", "./react")`, `./react/foo.bar` will be served at `/app/foo.bar`. I would suggest modifying the React app to use relative urls or set some kind of "base path" setting to `/app` to load the assets correctly. The fix depends on what build tool / framework you're using to compile the React app. – Dogbert Jun 12 '22 at 06:33
  • @Dogbert when you say relative paths, in my index.html which was generated by npm run build, I can see all link rels start with either `/` or `/static`. Currently if my `react` folder is mounted on `/` I can see the requests are sent to localhost/* where * is either empty or static. Do you suggest changing these `/`, `/static` paths in the index.html to `./` and `./static/` respectively? – RequireKeys Jun 12 '22 at 06:46
  • @Dogbert nevermind I figured it out : `.service(afs::Files::new("/app", "./react-front").index_file("index.html"))`. And then changed all my link rels to start at `/app` and then register a separate router for `/` which serves just the `index.html` page. – RequireKeys Jun 12 '22 at 06:53

0 Answers0