React router with Caddy

I am trying to serve a react application that utilizes react router using Caddy.

Caddyfile:

subdomain 

redir /ui /ui/
handle_path /ui/* {
    root * /app/build/
    file_server
}

Relevant portions of the docker-compose:

 caddy:
    image: img
    restart: always
    network_mode: bridge
    container_name: caddyContainer
    ports:
      - "443:443"
      - "80:80"
    env_file:
      - ./CaddyEnv.env
    volumes:
      - caddy_data:/data
      - caddy_config:/config
      - ./Caddyfile:/etc/caddy/Caddyfile

and my package.json file begins:

  "name": "name",
  "version": "0.1.0",
  "homepage": "/ui/",
...
}

This lets it know it starts from “/ui/”.

React router seems to be working because when I go to localhost/ui/check (one of my react router routes), it renders correctly. However when I put it up using Caddy and route to subdomain/ui/check, I get a 404 page cannot be found.

I saw something online about “try files”, but I was not sure if that was what I wanted, because it does not seem to be a dynamic approach. Maybe I misunderstood?

Yeah, try_files is what you want here. Basically for react router, you want any path that doesn’t map to a file on disk to actually serve index.html so that the react router JS code can look at the URL to load the right page. It’ll look like this:

foo.example.com {
	redir /ui /ui/
	handle_path /ui/* {
		root * /app/build
		try_files {path} /index.html
		file_server
	}
	handle {
		# Fallback for any request not otherwise handled
	}
}

Basically this says “if the request path (i.e. {path}) is to a file that exists on disk (i.e. root + path = file on disk) then rewrite to that (no-op); if not, then see if there’s an index.html on disk and rewrite to that”

1 Like

Awesome this works! had assumed when i saw that online that I had to put the path in manually, and thats why I thought it was not dynamic. But this works, covers all paths

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.