Rewrite for a Single Page Application

1. Caddy version (caddy version): V2

2. How I run Caddy:

Caddyfile

a. System environment:

OSx

b. Command:

caddy run

c. Service/unit/compose file:

Paste full file contents here.
Make sure backticks stay on their own lines,
and the post looks nice in the preview pane.

d. My complete Caddyfile or JSON config:

appdomain.com {
	try_files {path} /
    root * ./client/dist
	file_server
}


ted.com {
	rewrite * /ted{uri}
	route {
		try_files {path} /
		root * ./client/dist
		file_server
	}
}

bobby.com {
	rewrite * /bobby{uri}
	route {
		try_files {path} /
		root * ./client/dist
		file_server
	}
}

3. The problem I’m having:

I have a single page nuxt application which is serving the app at say appdomain.com. Ted has a blog at appdomain/ted and Bobby has a blog at appdomain/bobby

I want to be able to rewrite ted.com to appdomain/ted and bobby.com to appdomain/bobby.

I am trying the above configuration to serve the built files and rewrite the domains but it isn’t helping. Pls help.

4. Error messages and/or full log output:

5. What I already tried:

6. Links to relevant resources:

What version exactly? It matters. Run caddy version to see the exact version number.

If you use route, it overrides the predetermined directive sorting order. In this case, this will mess things up, because try_files depends on root being set before it, so that it knows where to look for files on disk.

In this case, you don’t need route at all, because rewrite is already ordered before try_files. Do this instead:

ted.com {
	root * ./client/dist

	rewrite * /ted{uri}
	try_files {path} {path}/ /ted/

	file_server
}

I assume you have a ./client/dist/ted/ directory. Having try_files fallback to /ted/ is important, because otherwise it would serve the index.html in ./client/dist/ instead of the one in ./client/dist/ted/.

v2.4.2

I have tried without the route block as well. The thing is that /ted is not a physical route. ted is a route parameter that decides what to load on that page.

the rewrite does not happen. It is loading the index file in all scenarios and not rewriting to /tenant.

I have moved to a subdomain based approach instead of a route based approach for now, where I am simply routing the domain to the same root and doing the tenant resolution at an app level. But I would like to understand how something like this would work.

FYI,

I missed out on this part -

try_files {path} {path}/ /ted/

As you said, the /ted/ is necessary. Will this work on a tenant based approach where ted is a route parameter or does ted have to be a physical directory ?

Please upgrade to v2.4.5, then!

The way file_server works is by taking the defined root, then appending the current request path to it, and looking for a file on disk at that location.

The try_files directive, similarly, will rewrite to the first matching root + argument. So if none of them match, no rewrite will happen. So if there’s no ./client/dist/ted/ at least, then no rewrite happens.

Thank you so much for the prompt reply. This makes it very very clear. I love the speed of replies on queries by the team! All the very best!

1 Like

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