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

Support for Multiple Beacon Sites with Distinct Domains and Shared Root Path (/) in Single-App Configuration #721

Closed
guidotripaldi opened this issue Jan 9, 2025 · 1 comment · Fixed by #723

Comments

@guidotripaldi
Copy link
Contributor

guidotripaldi commented Jan 9, 2025

Is your feature request related to a problem? Please describe

Currently, in a single-app configuration, Beacon does not support having two distinct beacon sites, each distinguished by a different host, when both point to the root path (/) within the router scope. For example, the following configuration works when each site has a distinct path:

# lib/my_app_web/router.ex

scope "/", MyAppWeb, host: ["example1.com"] do
  pipe_through [:browser, :beacon]
  beacon_site "/example_page_1", site: :example1
end

scope "/", MyAppWeb, host: ["example2.com"] do
  pipe_through [:browser, :beacon]
  beacon_site "/example_page_2", site: :example2
end

However, the following configuration is not supported, where both sites share the root path (/):

# lib/my_app_web/router.ex

scope "/", MyAppWeb, host: ["example1.com"] do
  pipe_through [:browser, :beacon]
  beacon_site "/", site: :example1
end

scope "/", MyAppWeb, host: ["example2.com"] do
  pipe_through [:browser, :beacon]
  beacon_site "/", site: :example2
end

This limitation means that it is impossible, if you need to deploy a single-app project, to have two or more distinct domains/subdomains (e.g., https://example1.com/ and https://example2.com/) pointing to their respective Beacon sites without including the page name in the URL.

Describe the solution you'd like

Introduce a new configuration option, site_domain, in the Beacon site configuration within runtime.exs. This option allows specifying the domain (e.g., "example1.com"), which will be set as the host in the router scope for that site. With this enhancement, sites configured with site_domain will function independently, even with the root path (/).

If site_domain is not set, the behavior remains unchanged, maintaining backward compatibility.

Additional Context

The site_domain option will be matched against its value in the reachability test Beacon.Router.reachable?. If it succeeds, the site will be booted

Example Configuration

# config/runtime.exs

config :beacon,
   ...,
  example1: [
      site: :example1,
      site_domain: "example1.com",
      # other site-specific configs
    ],
  example2: [
      site: :example2,
      site_domain: "example2.com",
      # other site-specific configs
    ],
  ...
  ]
# router.ex
...
scope "/", MyAppWeb, host: ["example1.com"] do
  pipe_through [:browser, :beacon]
  beacon_site "/", site: :example1
end

scope "/", MyAppWeb, host: ["example2.com"] do
  pipe_through [:browser, :beacon]
  beacon_site "/", site: :example2
end
...

With this enhancement, the URLs https://example1.com/ and https://example2.com/ will correctly point to their respective Beacon sites. The proposed feature is fully backward compatible.

If you'd like, I'm ready to submit a PR (https://github.com/guidotripaldi/beacon/tree/add-site-domain) for this feature. Please let me know if any adjustments are needed for the PR.

@leandrocp
Copy link
Contributor

Hi @guidotripaldi a fix for this problem is on the way and is kinda similar to your proposal but it works with endpoints instead of a runtime configuration.

In Phoenix there are essentially 2 configs for :host, one in the router and another one in the Endpoint itself, and they must match in order to make routes and links work properly, so fixing the router only is not enough. The :host config in the router defines the route that matches a request but the generation of links is driven by the endpoint.host config. In short the setup will look like:

Your App
  |
  | -- Beacon.ProxyEndpoint
           |
           | -- Site A Endpoint
           | -- Site B Endpoint

This way we can properly check for host conflicts and also dispatch requests to the correct route. You can also see the code for the Proxy Endpoint in that PR, there's not much, just forwarding the request to the designated site endpoint or the default app's endpoint if not using multiple sites.

But setting it up in the host app is not that much straightforward so we're working on Igniter (mix) tasks to help generate the files and the configuration which results in these changes BeaconCMS/beacon_demo#19 (this PR in the beacon_demo repo won't be merged, it's there only to help debug/test this setup).

So the last piece of the puzzle is finishing the Igniter tasks and documentation. We can coordinate this effort if that's something you'd like to tackle, and thanks for the interest!

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

Successfully merging a pull request may close this issue.

2 participants