Comments (8)
Even the most "SEO-optimized" URL will end up either as a bookmark or an entry in the browser history and therefore we have no problem with "ugly" URLs.
I would disagree... I personally use individual URLs very often. Especially with the autocomplete of modern browsers
Example:
- I enter 'gith'
- I get
- https://github.com/
- https://github.com/open-wc/open-wc
- https://github.com/webpack-contrib/karma-webpack
- ... (as these have been my last/most visited URLs in the past days)
- I want to limit more so I can just autocomplete + type more e.g. 'https://github.com/pol'
so by just selecting the appropriate URL I can go to where I need to be...
If it was all just
- I enter 'gith'
- I get
that experience would be rather different.
so I agree storing the full state in the URL is not possible for an application... but certain entry point should still have their easy human-readable path...
Unfortunately, I don't have a ready and good alternative solution... I guess it should be a combination of a "critical path" + data.
e.g. https://my-app.com/foo/bar?dataId=lasdflgue32343
How to best do this while still decoupling most data from the url and working with multiple teams who can give "hints" on what their feature component's url should be... I'm also not sure
from micro-frontends.
@brion-fuller , I have faced the same challenge in one of my recent projects. We were trying to encapsulate all ui for a micro service in single web component (custom element) and had a shell application to compose these elements in some fashion. One requirement for us was that each view should be addressable by url to allow bookmarks.
The way we solved the problem was to expect a view
attribute in each web component and parse this value in the web component to show a specific view. For instance, we had something like <title-app view="/view/1"></title-app>
. So, it is much like routing, but instead of playing with the URL, the component simply expects it to be passed in through the view
attribute. Now, this was the first piece of the puzzle. It allowed us to instantiate any view in that web component simply by passing an attribute. No URLs so far.
In the shell application that composed these components, we applied a simple heuristic for routing: /app/:componentName/**:view
. More specifically, every url that started with /app/
, we expected the next segment to be the componentName
. So, if it was /app/title-app
, we would create and append the title-app
component to the DOM. The remainder of the url was passed into the view
attribute. For instance, the url /app/title-app/edit/3
would create an element like <title-app view="/edit/3"></title-app>
.
This allowed us to serve up our web components in a shell application, but also able to use them in other web applications that works differently. For instance, we used some of these components in a ASP.Net web forms application, without making any changes.
from micro-frontends.
With https://github.com/square/misk-web, our initial approach has developed into two idioms for sub-routes.
1. Sub-routes can only be extensions of the url domain of the component
Component | Component URL Domain | Allowed Sub-Routes |
---|---|---|
<foo-component/> |
/foo/ |
/foo/* |
<bar-component/> |
/category/bar/ |
/category/bar/* |
2. Components can not have overlapping url domains
Assume in the following example that components are added in the order of the table rows.
Component | Component URL Domain | Url Domain |
---|---|---|
<foo-component/> |
/foo/ |
Valid |
<bar-component/> |
/foo/bar/ |
Invalid |
<baz-component/> |
/category/baz/ |
Valid |
<bip-component/> |
/category/bip/ |
Valid |
<category-component/> |
/category/ |
Invalid |
from micro-frontends.
My team and I are also working on the same. We aren’t at the stage yet where we can split our monolith yet, but this question has been on our mind as well.
from micro-frontends.
Lay down your burdens you need to rethink, what URLs have been originally been used for - to link to an application at a certain state.
In the time of SPAs we abused the URL for all sort of state-related things in our apps - we used it to route to a certain state of the app (by associating URLs with components). If we were to navigate to another state of the app, we triggered fake URL changes. However as time passed by, we figured out, that the state of a SPA needs special care and thus we all craved a dedicated state management (being it Redux, Mobix, ...).
If you look at the typical things the router in SPAs is doing right now, it becomes clear, that this is just an awkward mechanism to change the state of the app. But for changing the state of an app we do not need a router - we can just dispatch the corresponding actions and have generic router-less state router component listen for the state changes and thus load components accordingly.
If you see it that way you will solve the main problem - different components competing for using the URL (by using a router) as their sole source of state initialization. If all components are decoupled from the URL and are only using an in-memory based native state management aware routing, they will now all happily live together on the same page. For communication between components you have to use either DOM events or attributes.
How about "deep-linking" into micro frontend based apps? Depending on your micro frontend architecture - you might have a glue app (we call it the frame in our architecture) that is orchestrating all the components. As all components have been decoupled from the URL, the glue app can now utilize it again to (re)store the state of each component. The frame knows about the state changes between components and can encode this global state in the URL. Usually the state is to big to be kept in the URL anyway and thus it is feasible to store the serialized application state either locally or remote and associate it with a GUID / token that allows for restoring - i.e. once the frame has been passed the GUID it uses it to restore the state of all components.
It can do so, by either replaying all actions against all components or by storing not the actions but the GUIDs of the local state of components itself and let them handle the restoring of their inner local state by themselves.
That is the generic idea; we are using it in production by replacing the Angular Router in a Angular Elements app with a native NgRx aware (but still somehow compatible version) URL-less one. That way we can load multiple Angular Elements apps on one page.
from micro-frontends.
@adrw I have to give your micro frontend architecture a try. Thanks for posting it! If I understood it correctly you have certain conventions what URLs (and sub paths) are mapped to certain components. This is a viable choice, but it needs coordination between teams to avoid naming collisions. Ultimately it weakens the isolation of components and might lead to problems in scaling - i.e. when certain conventions cannot be enforced easily any more (read: third party supplied components).
In our (above) approach we simply remove the dependency on the URL altogether, while still maintaining the possibility of deep-linking into app state. This allows for a better isolation of components by avoiding potential naming collisions on the URL.
Of course, GUID-based URLs are not so pretty(TM) and might scare away SEO magicians; but people simply do not memorize URLs any way. Even the most "SEO-optimized" URL will end up either as a bookmark or an entry in the browser history and therefore we have no problem with "ugly" URLs.
from micro-frontends.
@ChristianUlbrich I really like the idea of separating state from the url. This is something I have tried to solve and still haven't found a good solution for.
I see the same problems as above. I do agree that URL is critical in the User Experience as this is a functionality commonly used and known to shortcut to desired pages. But how does the frame know when a components state should be referenced in the url someway?
Lets say I have a site and a team is working on a Users component and they want to display user "10". This is easy with state as we will see a request to get user "10" and then the component will populate. Now the problem comes in on refresh, lets say the clients wants user "11" and just replaces the url "/user/10" => "user/11" how is this translated and known?
from micro-frontends.
Hi there,
I actually solved that issue by taking inspiration from this repo:
https://github.com/me-12/single-spa-portal-example
He does reverse proxying through Webpack. It's actually unnecessary, you can just pass the URL where the entrypoint.js files are hosted.
Hope that help
from micro-frontends.
Related Issues (20)
- Nodemon HOT 1
- Apply for translation HOT 7
- Server Side Rendering HOT 1
- Can we achieve this with angular elements HOT 1
- Micro-frontends as an advantage to using web components with a headlessCMS
- Team Blue Missing! HOT 1
- share common resources between teams HOT 3
- Thanks about micro-frontends concept. HOT 1
- Any ETA for navigation reference? HOT 4
- micro frontend
- Added Portuguese Translation HOT 1
- Added Korean Translation HOT 3
- Misleading diagram wrt frameworks HOT 2
- Why did you start to call component architecture as "microfrontends"? HOT 5
- How to have error handling mechanism in microfrontends? HOT 1
- Universal Composition: Render Call Question HOT 2
- Integrate micro frontend from different repo? HOT 1
- Can we create composite app with React and Jinja Template together?
- Added Polish translation HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from micro-frontends.