Answers.Body: <p>Okay, the issue had to do with Craft not being able to match the URLs to the right site.</p>
  <p>I have been using custom aliases to define the site URLs, like this:</p>
  <ul>
  <li><code>@siteOrigin</code></li>
  <li><code>@siteOrigin/de</code></li>
  </ul>
  <p>...but defined the aliases in the <code>init()</code> method of the custom module. Apparently, that meant the aliases weren't available yet when the Request was handled, therefore always defaulting back to the main site.</p>
  <p>I moved defining the aliases to <code>config/general.php</code> using a static method in the module, effectively making the aliases available earlier in the (cough) “parse order”.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-09-13T15:04:25.150Z
Answers.LastActivityDate: 2024-09-13T15:04:25.150Z
Answers.UserDisplayName: Low
Body: <p>Consider the following. I have two sites:</p>
  <ul>
  <li><code>site</code>: the main site</li>
  <li><code>site_de</code>: the German version of the site</li>
  </ul>
  <p>Those two sites have the following Base URLs:</p>
  <ul>
  <li><a href="https://my.site.test" rel="nofollow noreferrer">https://my.site.test</a></li>
  <li><a href="https://my.site.test/de" rel="nofollow noreferrer">https://my.site.test/de</a></li>
  </ul>
  <p>I have a Pages section that is available in both sites, with Entry URIs that look like this:</p>
  <ul>
  <li><code>{slug}</code></li>
  <li><code>{slug}</code></li>
  </ul>
  <p>I want all requests to end up in my main index template, which will load up the entry requested, making <code>entry</code> available in it. So there's only a single <code>templates/index.twig</code> and a single <code>web/index.php</code>, no subfolders or duplicates, and I'd like to keep it that way, to keep things DRY.</p>
  <p>Linking to other parts of the site can be done using <code>siteUrl('foo/bar')</code> which results in:</p>
  <ul>
  <li><a href="https://my.site.test/foo/bar" rel="nofollow noreferrer">https://my.site.test/foo/bar</a></li>
  <li><a href="https://my.site.test/de/foo/bar" rel="nofollow noreferrer">https://my.site.test/de/foo/bar</a></li>
  </ul>
  <p>...respectively. This is good.</p>
  <p>For a Pages entry 'About us', these entry URLs are generated:</p>
  <ul>
  <li><a href="https://my.site.test/about-us" rel="nofollow noreferrer">https://my.site.test/about-us</a></li>
  <li><a href="https://my.site.test/de/about-us" rel="nofollow noreferrer">https://my.site.test/de/about-us</a></li>
  </ul>
  <p>The issue here is that the German URL will trigger a 404, as Craft will try and match the entry with the URI <code>de/about-us</code>, which does not exist; <code>about-us</code> is stored in the DB.</p>
  <p>If I change the settings to the Base URLs <em>both</em> pointing to <code>https://my.site.test</code> and then the German entry URI to <code>de/{slug}</code>, the German URL <em>will</em> work. <em>But</em> pointing to <code>siteUrl('foo/bar')</code> will point to the main site, <em>without</em> <code>/de</code> in there.</p>
  <h3>In conclusion</h3>
  <p>Is there a way to have both? So, keep <code>/de</code> in the Base URL (as it is the base of that site), but have it match <code>de/about-us</code> too <em>without</em> having to define the country code in the Entry URI?</p>
  <p>Side note, I have a custom module in place that changes the default site based on the incoming URI.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-09-13T13:28:19.620Z
Comments.Text: I've tested a site with a similar setup that I have and for me it works fine - my base URL in settings for the second site includes the country code, while the first site has none. Then using a single shared template for both sites and using `siteUrl()` in there includes the country code on the second site but not on the first. Maybe something to do with your custom module??
Comments.UserDisplayName: James Smith
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-09-13T13:39:25.737Z
Comments.Text: @JamesSmith what does your section's entry URI format look like? In the above setup, the `siteUrl()` works as expected, but entry URLs throw 404s unless I add the country code in the entry URI format, which I'm hoping to avoid.
Comments.UserDisplayName: Low
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-09-13T13:46:44.613Z
Comments.Text: The Entry URI Formats for both sites are the same as each other: in this case `resources/{slug}`. One other difference might be my template routing - for which I've set up a symlink at `templates/de` pointing to `templates/default` - however that's not necessary if you just put all your templates at the root of `templates` instead of in site-specific sub-directories. (Also, I'm checking this in Craft 4)
Comments.UserDisplayName: James Smith
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-09-13T13:54:32.660Z
Comments.Text: FWIW, disabling the module makes no difference. I'm using Craft 5.
Comments.UserDisplayName: Low
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-09-13T14:39:01.517Z
Comments.Text: @Low FWIW, the way you've set this up should work out of the box – i.e. Craft should set the current site based on the incoming URL and there shouldn't be a need for that custom module, multiple index.php files (that hasn't been required since Craft 3.0), symlinks or any other hacks. So if that German URL 404s, something is wrong somewhere :)
Comments.UserDisplayName: Mats Mikkel Rummelhoff
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-09-13T14:40:07.967Z
Comments.Text: @Low Shot in the dark, but are you potentially overriding the current site URL with a `CRAFT_WEB_URL` variable in your .env file? If that's the case, try removing that.
Comments.UserDisplayName: Mats Mikkel Rummelhoff
Tags: <localization><multi-site><routes>
Title: Site baseUrl with locale and entry URI matching
ThreadText: # Site baseUrl with locale and entry URI matching
  
  (Asked by: username_0 on 2024-09-13)
  
  Consider the following. I have two sites:
  
  * `site`: the main site
  * `site_de`: the German version of the site
  
  Those two sites have the following Base URLs:
  
  * <https://my.site.test>
  * <https://my.site.test/de>
  
  I have a Pages section that is available in both sites, with Entry URIs that look like this:
  
  * `{slug}`
  * `{slug}`
  
  I want all requests to end up in my main index template, which will load up the entry requested, making `entry` available in it. So there's only a single `templates/index.twig` and a single `web/index.php`, no subfolders or duplicates, and I'd like to keep it that way, to keep things DRY.
  
  Linking to other parts of the site can be done using `siteUrl('foo/bar')` which results in:
  
  * <https://my.site.test/foo/bar>
  * <https://my.site.test/de/foo/bar>
  
  ...respectively. This is good.
  
  For a Pages entry 'About us', these entry URLs are generated:
  
  * <https://my.site.test/about-us>
  * <https://my.site.test/de/about-us>
  
  The issue here is that the German URL will trigger a 404, as Craft will try and match the entry with the URI `de/about-us`, which does not exist; `about-us` is stored in the DB.
  
  If I change the settings to the Base URLs *both* pointing to `https://my.site.test` and then the German entry URI to `de/{slug}`, the German URL *will* work. *But* pointing to `siteUrl('foo/bar')` will point to the main site, *without* `/de` in there.
  
  ### In conclusion
  
  Is there a way to have both? So, keep `/de` in the Base URL (as it is the base of that site), but have it match `de/about-us` too *without* having to define the country code in the Entry URI?
  
  Side note, I have a custom module in place that changes the default site based on the incoming URI.
  
  **Tags:** localization, multi-site, routes
  
  > **Comments:**
  > **username_1**: I've tested a site with a similar setup that I have and for me it works fine - my base URL in settings for the second site includes the country code, while the first site has none. Then using a single shared template for both sites and using `siteUrl()` in there includes the country code on the second site but not on the first. Maybe something to do with your custom module??  
  > **username_0**: @username_1 what does your section's entry URI format look like? In the above setup, the `siteUrl()` works as expected, but entry URLs throw 404s unless I add the country code in the entry URI format, which I'm hoping to avoid.  
  > **username_1**: The Entry URI Formats for both sites are the same as each other: in this case `resources/{slug}`. One other difference might be my template routing - for which I've set up a symlink at `templates/de` pointing to `templates/default` - however that's not necessary if you just put all your templates at the root of `templates` instead of in site-specific sub-directories. (Also, I'm checking this in Craft 4)  
  > **username_0**: FWIW, disabling the module makes no difference. I'm using Craft 5.  
  > **username_2**: @username_0 FWIW, the way you've set this up should work out of the box – i.e. Craft should set the current site based on the incoming URL and there shouldn't be a need for that custom module, multiple index.php files (that hasn't been required since Craft 3.0), symlinks or any other hacks. So if that German URL 404s, something is wrong somewhere :)  
  > **username_2**: @username_0 Shot in the dark, but are you potentially overriding the current site URL with a `CRAFT_WEB_URL` variable in your .env file? If that's the case, try removing that.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2024-09-13. Score: 1 | Accepted answer
  
  Okay, the issue had to do with Craft not being able to match the URLs to the right site.
  
  I have been using custom aliases to define the site URLs, like this:
  
  * `@siteOrigin`
  * `@siteOrigin/de`
  
  ...but defined the aliases in the `init()` method of the custom module. Apparently, that meant the aliases weren't available yet when the Request was handled, therefore always defaulting back to the main site.
  
  I moved defining the aliases to `config/general.php` using a static method in the module, effectively making the aliases available earlier in the (cough) “parse order”.
  
  
  ---
  
  