-
-
Notifications
You must be signed in to change notification settings - Fork 572
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
Prefix path router #3592
base: main
Are you sure you want to change the base?
Prefix path router #3592
Conversation
❌ Deploy Preview for volto failed. Why did it fail? →
|
Passing run #7234 ↗︎
Details:
Review all test suite changes for PR #3592 ↗︎ |
Link view now working, Image view still has issues with the download link which is not working (see this example) |
During the Volto Team meeting we agreed that we would have to put in place a whole round of Cypress tests pointing to a deployment using this. I can imagine that in the future will be quite easy to break the whole feature if one does not have in mind it. I think that could be time consuming, but might not have much difficulty. What do you think? |
@mamico @giuliaghisini could you share the reverse proxy config you have on such deployments? |
We should add some documentation about how to setup such a deployment. |
@sneridagh our deployment config is a bit complicated because there are several urls and frontend names, and it's made in varnish and not in nginx/apache. The conf itself for using this branch is easy. Here is an example for nginx:
|
@cekk One other thing is important to document, the prefix path /foo corresponds to the Plone root, not a /foo subfolder in Plone. |
Yes, /foo points to the root of Plone site |
@cekk To make it work I had to launch Volto with:
I would have expect that given a RAZZLE_PREFIX_PATH, the other would have adjusted automatically (as seamless mode promises). I am doing something wrong? because given a look at the code, it seems it should, right? |
@cekk Forget the question, I'm still asleep. 😅 |
Added tentative tests: #3719 see comments. |
I would like to take this forward. Locally looks good. I will checkout this branch on one of our projects first and see if I find some issues. State of this PR:This PR is based on There is another approach in this PR, which uses a store enhancer middleware to prefix all the router paths(amending history accordingly) and modified What's left are the cypress tests #3719 which should also account for prefix path in the URLs. I will try to have a look into them. I personally like the basename approach and let react-router handle the prefixes. However, we need to think about the non-router links and static assets. What do you think @sneridagh @davisagli @tiberiuichim @pnicolli ? |
@giuliaghisini @nileshgulia1 @sneridagh any chance we have this feature in master? |
I updated the branch and run:
Then I got the error: ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options has an unknown property 'publicPath'. These properties are valid:
object { allowedHosts?, bonjour?, client?, compress?, devMiddleware?, headers?, historyApiFallback?, host?, hot?, http2?, https?, ipc?, liveReload?, magicHtml?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, port?, proxy?, server?, setupExitSignals?, setupMiddlewares?, static?, watchFiles?, webSocketServer? }
at validate (/home/user/git/volto/node_modules/webpack-dev-server/node_modules/schema-utils/dist/validate.js:115:11)
at new Server (/home/user/git/volto/node_modules/webpack-dev-server/lib/Server.js:231:5)
at new razzleDevServer (/home/user/git/volto/node_modules/razzle/config/razzleDevServer.js:10:5)
at /home/user/git/volto/node_modules/razzle/scripts/start.js:181:33
at processTicksAndRejections (node:internal/process/task_queues:96:5) I'll take a look at it. |
@wesleybl it's due to the changes in razzle.config.js |
@tiberiuichim I fixed this in: f011df6 |
@sneridagh @nileshgulia1 add core test with prefixed path. Can you take a look please? Can we merge this PR? |
|
||
For a production setup, when hosting Volto behind a proxy HTTP server, you can configure your rewrite rules to something like the following, in this case for Apache. | ||
|
||
```apache |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The recommended deployment setup is using Docker. I know that the documentation about this is in a sorry state, but we cannot add more confusion about this by dropping an Apache
config here. I don't have a good solution for this one :(
In the upcoming sprints we should work on documenting properly the deployment story.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sneridagh would it be an idea to use an example with nginx
, since docker uses nginx
?
RAZZLE_PREFIX_PATH=/level1/level2 RAZZLE_API_PATH=http://example.com/level1/level2 yarn start | ||
``` | ||
|
||
Note, as you'll be integrating Volto with an existing website, you need to configure `config.settings.externalRoutes` so that the router knows which routes it should consider internal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need more elaboration and reasoning why this is necessary.
``` | ||
|
||
The prefix location will be used regardless of how you start Volto, whether in development or production mode. | ||
When developing, though, if your backend is something other then `http://localhost:8080`, you'll need to provide your own solution for how to handle things. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So in development I don't have to set it up and act as I'm in the root then?
@@ -44,7 +46,7 @@ describe('actions Tests', () => { | |||
cy.get('a[class="icon-align-name"]').should( | |||
'have.attr', | |||
'href', | |||
'/my-page-1/contents', | |||
`${prefixPath}/my-page-1/contents`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we do it more elegant by invoking the baseUrl
from Cypress config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sneridagh yes would be. And it would be less code to change. When I have time I will change this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sneridagh I started looking into this but that won't be possible. baseURL
contains the URL with the domain. For example:
http://localhost/foo
But links in HTML are relative. For example:
/foo/my-document
@@ -837,38 +842,14 @@ Cypress.Commands.add('clickSlateButton', (button, timeout = 1000) => { | |||
}).click({ force: true }); // force click is needed to ensure the button in visible in view. | |||
}); | |||
|
|||
// Helper functions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 I started this already in a recent PR. A merge might be needed.
packages/volto/razzle.config.js
Outdated
if (target === 'web' && dev) { | ||
config.devServer.devMiddleware.publicPath = prefixPath; | ||
} | ||
const pp = config.output.publicPath; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No cryptic vars, please.
And regarding the dev server, is it necessary to also use the prefix while developing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In webpack 5, the public path in dev mode needs to be prefixed as well. http://localhost:3001/foo/static/js/client.js
@@ -130,64 +136,66 @@ function Controlpanels({ | |||
: []; | |||
const { filterControlPanels } = config.settings; | |||
|
|||
const filteredControlPanels = map( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get the reason for this. Which is the rationale?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 3ad97df, @nileshgulia1 performed a validation to see if there was a controlpanel. I kept that validation. See below:
This prevents an on-screen error if the backend does not return the controlpanels.
flattenToAppURL, | ||
isInternalURL, | ||
URLUtils, | ||
} from '@plone/volto/helpers/Url/Url'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We decided not using barrel indexes in Volto anymore, so going back here is not an option.
@@ -109,7 +110,7 @@ const UniversalLink = ({ | |||
} else if (isDownload) { | |||
tag = ( | |||
<a | |||
href={flattenToAppURL(url)} | |||
href={addPrefixPath(flattenToAppURL(url))} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So what if instead of modifying any invocation to flattenToAppURL
(and I'm sure we are missing a lot), we incorporate this to it? I think it's not acceptable to modify every single apparition of it and the future ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sneridagh I encountered challenges when attempting to integrate it directly into the "flattenToAppUrl" function, primarily due to the occurrence of duplicate prefixes because we already have a router basename set in this PR. Just to let you know we have recently deployed https://water.europa.eu/freshwater which is using bits and pieces of this PR. We did some customizations which will be removed when volto 17 is integrated into that site. I'm not sure if we applied special deployment tactics maybe @olimpiurob or @claudiaifrim knows more about this context.
Just for people who wants to test this feature, currently for development we use
RAZZLE_PREFIX_PATH=/freshwater RAZZLE_INTERNAL_API_PATH=http://x.x.x.x:port/Plone yarn start
You might also need to set RAZZLE_API_PATH
if your backend lives in another site than /Plone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nileshgulia1 I didn't understand the difficulty of using addPrefixPath
inside flattenToAppURL
. Are there situations where it is not necessary to use addPrefixPath
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wesleybl Basically paths that are rendered using <Link />
or <UniversalLink/>
need not be prefixed. This also includes hashlinks. In volto-prefixpath we don't set the router basename as prefix, thus we use this approach.
The image components in our addons were our major source of trouble because in volto 17 we have a single Image component and the rule is to use it everywhere to render images. So, we use this approach until we migrate all addons to volto 17.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@plone/volto-team We need to talk about this in our next meeting.
Finally I took a long look at it, and TBH I have lots of doubts. Sorry to be that pessimistic, but it's my sincere opinion.
I understand that this is a long requested feature. However, implement this if our Router does not support it OOTB (which is what it's happening) seems to me a lot. A lot of code to maintain, a lot of pitfalls that lie ahead if we adopt this now.
Take the example of Remix. They just implemented this, and baked it into latest RR and their Vite build this last month. They did it by using a global baseName
support: https://remix.run/blog/remix-vite-stable#basename-support
I can tell you this, complicating Volto codebase will only make harder future refactors of its fundamental components. I don't want this to happen. I'm also convinced that make the current tests pass is not enough. I'm sure we have lots of edge cases uncovered.
This is intrusive enough for it to have its own major release alone, and I won't include it in 18... It has enough changes in there, and it's important enough already, being the targeted Plone 6.1 release, and we are already at the end of the alpha phase.
Let's discuss it in the next meeting, let's see if we can polish rough edges. I'd love that everyone involved and interested be there to talk about it.
@sneridagh so would this be for Volto 19? Any predictions on when Volto 19 will start? |
It already has, by virtue of this pull request. I think this is the second feature designated for Volto 19, after my PLIP for timezone, date, and time support. I think it would be good to create a PLIP for discussion and add it to the Volto Roadmap GitHub project. I also created a 19.x.x milestone to start tagging issues and pull requests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've put this item on the agenda for the next Volto Team Meeting to discuss documentation, implementation details, targeting a Volto release, and possibly other items that come up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this page needs to have better narrative structure, such as the following:
- Introduction that states the essential and basic requirements for a deployment, regardless of root or non-root. This might already exist somewhere in the Deploying section. Side note: that entire section needs to be cleaned up, and I think the index page should have this introduction as its introduction, so we can easily refer to it. We can also use an include to avoid copy-paste drift.
- Clarify what these requirements do and why they are necessary.
- Then add to the basic requirements those things that are required for a non-root deployment.
- Again, clarify what these requirements do and why they are necessary.
- Finally show examples of implementation details, whether it is Apache, nginx, or whatever. It is OK to have multiple examples. In fact I would use Sphinx Design with a tabbed code example interface.
Minutes from the @plone/volto-team meeting:
|
Enable to publish Volto site under a prefixPath, for example
www.mymainsite.com/prefixPath