Introduce `createSearchParamsHistory`
Closed this issue · 1 comments
What problem is this solving
As the documentation says, both createWebHistory
and createWebHashHistory
have disadvantages.
createWebHistory
can not be used if the underlying server can't handle the required paths in some specific way.
Since, by default, when a server sees pathname
like this /users/123
it tries to return a file with name 123
from the users
directory even while only the index.html
is in the working directory. Trying opening such URL will fail with the 404 error.
❌ So, createWebHistory
can not be used when there is no ability to configure the server behaviour. In particular, in web extensions.
On the other hand, using of createWebHashHistory
don't allow to use the hash
for common things as scrolling to an element with id
same as in the hash
, and/or styling the element with :target
CSS selector, also for other things like using hash for storing local data, for example:
- a code in online code editors (
https://play.vuejs.org/
) - a decryption key in a file hosting like Mega (
https://mega.nz/
)
❌ Thus, using createWebHashHistory
limits the use of the hash to only store the route and nothing else. It's bad.
Proposed solution
The very simple alternative is just to store the route path as a key's value of searchParams
.
This:
- ✅ works everywhere, no need to perform a server configuration which may be not available,
- ✅ you can use
hash
for your own purposes, - ✅ no SEO problems like with using of
createWebHashHistory
(using of seachParams
for navigation is the older thing than "REST API-like" URLs of createWebHistory
).
It should look like this:
createRouter({
history: createSearchParamsHistory(),
routes: [
{ path: "/users/:id", component: UserComp, name: "User" },
{ path: "/admin", component: AdminComp, name: "Admin" },
]
});
And the URLs will look so:
/index.html?route=/users/123
/index.html?route=/admin
For both URLs /index.html
and /index.html?route=/users/123
any server will return the same "index.html" file with no problem.
Then the router will parse the input URL and do the things.
Also, it makes sense to allow to specify the searchParam
's key name (if the default route
is already used for another purpose):
createSearchParamsHistory({
name: "vueRoute"
})
/index.html?vueRoute=/admin
I sure it's easy to implement.
You just only need to parse/write the route path from/to the specific searchParams
' key instead of pathname
, or hash
.
That's all.
createSearchParamsHistory
will be definitely better than createWebHashHistory
.
Describe alternatives you've considered
No response
Interesting idea! It does sound like you could use the hash history. Note that you can still store other data with a virtual hash property. You do lose the CSS :target
property as a tradeoff.
You mention 3 other advantages, but the first two apply to the hash history as well, and the last one isn't a concern in a web extension.
In any case, this can be built as a standalone library outside of vue-router (that was one of the advantages of extracting the histories 😄). I don't think this kind of history should be included in vue router because I wouldn't recommend it over the other histories (for the reasons mentioned above), but I would love to see it as a standalone open-source library! It shouldn't be too hard by copying an existing history and replacing the way it handles the path, so you should definitely give it a try. FYI: I offer consultancy for anybody needing help with their products