-
Notifications
You must be signed in to change notification settings - Fork 35
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
Pattern to exclude any URLs with query strings. #329
Comments
This seems to work for me for query strings with an <script type="speculationrules">
{
"prerender": [
{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "*\\?*=*" } }
]
}
}
]
}
</script> Example here: https://prerender-demos.glitch.me/no-query-params.html However it doesn't exclude query strings without a value (e.g. |
Hi @tunetheweb, Thank you for the quick respond and suggestion. Unfortunately, I have tried that pattern. It makes all links, even the normal links (without query string present), it's not prefetched. In the example that you provided https://prerender-demos.glitch.me/no-query-params.html, this one In my tests, if we add Any other suggestion? Again, thank you :) |
This is really a question for https://github.com/whatwg/urlpattern. One thing you may not be aware of is that you don't have to use the string form of URL patterns. You can use the dictionary form too. So I think something like this (not tested) would work: { "not": { "href_matches": { "search": "(.+)" } } } I suggest playing around with the URL Pattern API directly which will make your testing go much faster. Just do (new URLPattern(whateverYouWouldPutForHrefMatches, { baseURL: document.baseURI })).test(targetURL) |
Hi @domenic, Thank you. I'll check out the URL Pattern API after this. |
@aryadhiratara I didn't have
@domenic I did not know that! I will add that to [our docs]https://developer.chrome.com/docs/web-platform/prerender-pages), however I cannot get it to work. This works: const pattern = new URLPattern({ search: '(.+)' }, { baseURL: "https://prerender-demos.glitch.me" });
console.log(pattern.test("https://prerender-demos.glitch.me/next.html")); // false
console.log(pattern.test("https://prerender-demos.glitch.me/next.html?query")); // true
console.log(pattern.test("https://prerender-demos.glitch.me/next.html?query=123")); // true But I tried several variants of that in Speculation Rules and not of it is accepted by Chrome: "href_matches": { search: "(.+)" } "href_matches": { "search": "(.+)" } "href_matches": "{ search: '(.+)' }" |
The second of those is syntactically closest, but For example, for all same-origin links with non-empty query strings: {"href_matches": { "pathname": "/*", "search": "(.+)" }} {"href_matches": "/*\\?(.+)"} (The backslash is necessary here because Or if you want absolutely everything with a non-empty query string, specifying the protocol explicitly wipes out inheritance (you can also specify the other components if you like, and in the string form you must): {"href_matches": { "protocol": "*", "search": "(.+)" }} {"href_matches": "*:*:*\\?(.+)" } The reason your comparison didn't work correctly is because (new URLPattern({baseURL: document.baseURI, ...whateverYouWouldPutForHrefMatches})).test(targetURL) At some point I should write a URL pattern explorer tool; despite our efforts to make as many things as possible natural, quirks persist. |
Thanks! Updated the demo. I think the key thing I was missing is that it seems like you need parentheses to access full regex functionality (i.e. to get access to the Anyway, that is definitely a URL Pattern issue and not for here. Confirmed it is all working for Speculation Rules once you know the syntax! So think this issue can be closed now. |
Just a quick additional note -- if you just want "has no query params", then instead of negating a "has query params" pattern, you could also use "and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "*\\?(.+)" } } could also be written { "href_matches": "/*\\?" } or { "href_matches": { "pathname": "/*", "search": "" } } |
Hi @jeremyroman, Need clarification. So if I need to exclude any URLs with query string, I should use this? <script type="speculationrules">
{
"prefetch": [{
"source": "document",
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": { "pathname": "/*", "search": "" } } }
]
},
"eagerness": "moderate"
}]
}
</script> |
This works too as given in my demo: <script type="speculationrules">
{
"prefetch": [
{
"where": {
"href_matches": "/*\\?"
},
"eagerness": "moderate"
}
]
}
</script> |
Hi @tunetheweb, Yes, that's what I'm trying to explain :) <script type="speculationrules">
{
"prefetch": [{
"source": "document",
"where": {
"and": [
{ "href_matches": "/*\\?*(^|&)" },
{ "not": {"href_matches": ""}}
]
},
"eagerness": "moderate"
}]
}
</script> It effectively excludes any URL with query strings while allowing normal URLs to be prefetched as intended. Logically, shouldn't this <script type="speculationrules">
{
"prefetch": [{
"source": "document",
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": { "pathname": "/*", "search": "" } } }
]
},
"eagerness": "moderate"
}]
}
</script> the results is the opposite; normal urls are excluded while urls with query strings able to be prefetch. However if use this <script type="speculationrules">
{
"prefetch": [{
"source": "document",
"where": {
"and": [
{"href_matches": { "pathname": "/*", "search": "" }}
]
},
"eagerness": "moderate"
}]
}
</script> It effectively excludes any URL with query strings while allowing normal URLs to be prefetched as intended. |
As |
ah, I finally got it. this explanation
is what missing from my understanding. Thank you very much @tunetheweb 🙏🏼 |
Context:
I'm looking for a regular expression pattern to exclude any URLs containing query strings using the Speculation Rules API.
I tested various patterns, but none worked as expected.
This simple pattern works:
But only if the url with query strings pointed to the same page.
For example,
https://domain.ext/?test-query
, the exclusion works.https://domain.ext/about/?test-query
, the exclusion doesn't work.https://domain.ext/about/?test-query
works.Following the example I found in MDN and Chrome’s documentation:
/*\\?*(^|&)add-to-cart=*
/*\\?*(^|&)category=*
I tests various exclusion pattern based from the example above. None of them are working as expected.
Any idea for the correct regex to exclude any URLs with query strings that will work?
Found Unexpected Behavior:
I accidentally found that when I use this
/*\\?*(^|&)
in thenot
href_match
value (it should matches URLs that contain a?
, and optionally, those followed by an&
)Full code:
The pattern inadvertently excludes normal URLs without query strings, preventing them from being prefetched while allowing URLs with query strings to be prefetched.
So I decided to test by emptying the 'not' value, and placed the URL in the (include)
href_match
Full code:
It effectively excludes any URL with query strings while allowing normal URLs to be prefetched as intended.
Could someone provide clarification on why this behavior occurs and how to correctly exclude all URLs containing query strings using the Speculation Rules API?
The text was updated successfully, but these errors were encountered: