Commit 8369d8f
feat(canonical): query param filtering, trailing slash & hash stripping (#713)
* feat(canonical): add query parameter filtering to CanonicalPlugin
Strips non-content-affecting query params (utm_source, fbclid, gclid, etc.) from
canonical and og:url tags to prevent duplicate content issues. Defaults to
whitelisting page, sort, filter, search, q, category, tag. Configurable via
queryWhitelist option. Also adds framework setup guides for Nuxt, Vue, React,
Svelte, and Angular.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* feat(canonical): add trailing slash normalization and hash stripping
Adds trailingSlash option (true/false/undefined) to enforce consistent
trailing slashes on canonical and og:url tags. Also strips hash fragments
from canonical URLs since search engines ignore them. Documents both
features.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix(canonical): resolve gaps in URL coverage and normalization
- Remove non-standard `og:see_also` from transformable URLs
- Add missing `og:audio`, `og:audio:url`, `og:audio:secure_url`,
`og:image:url`, `og:video:url`, `twitter:player`, `twitter:player:stream`
- Resolve `rel="next"` and `rel="prev"` link hrefs to absolute URLs
- Ensure normalization (query filtering, hash stripping, trailing slash)
runs after `customResolver` so it's never bypassed
- Export `DEFAULT_QUERY_WHITELIST` from `unhead/plugins` for extensibility
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* feat(canonical): resolve alternate, author, license, help, search, pingback links
Add rel="alternate", "author", "license", "help", "search", and "pingback"
to resolvable link rels. Most importantly, hreflang alternate links now
get resolved to absolute URLs which is critical for international SEO.
Canonical normalization (query filtering, hash stripping) only applies
to rel="canonical", not to these other rels.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* docs(canonical): update tag list with all resolved meta and link tags
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* chore(canonical): export CanonicalPluginOptions type
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix(canonical): address CodeRabbit review feedback
- Fix Vue docs: use `@unhead/vue/client` import path for createHead
- Fix React docs: use `@unhead/react/client` import path for createHead
- Fix Svelte docs: use createHead() in entry-client.ts instead of
useUnhead() which requires component context
- Fix normalizeCanonicalUrl: pass `host` as base to `new URL()` so
protocol-relative URLs (//example.com/...) are properly normalized
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* test: update export snapshots for DEFAULT_QUERY_WHITELIST
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* feat(canonical): strip all query params by default, make whitelist opt-in
Since the plugin is already opt-in, users should explicitly declare which
query params to preserve rather than relying on a default whitelist.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>1 parent 21a655a commit 8369d8f
4 files changed
Lines changed: 779 additions & 7 deletions
File tree
- docs/head/1.guides/plugins
- packages/unhead
- src/plugins
- test/unit/plugins
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | | - | |
22 | | - | |
23 | | - | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
24 | 35 | | |
25 | 36 | | |
26 | 37 | | |
27 | 38 | | |
| 39 | + | |
28 | 40 | | |
29 | 41 | | |
30 | 42 | | |
31 | 43 | | |
| 44 | + | |
32 | 45 | | |
33 | 46 | | |
34 | 47 | | |
| |||
50 | 63 | | |
51 | 64 | | |
52 | 65 | | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
53 | 147 | | |
54 | 148 | | |
55 | 149 | | |
| |||
59 | 153 | | |
60 | 154 | | |
61 | 155 | | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
62 | 161 | | |
63 | 162 | | |
64 | 163 | | |
| |||
116 | 215 | | |
117 | 216 | | |
118 | 217 | | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
119 | 317 | | |
120 | 318 | | |
121 | 319 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
6 | 23 | | |
7 | 24 | | |
8 | 25 | | |
9 | 26 | | |
10 | 27 | | |
| 28 | + | |
11 | 29 | | |
12 | 30 | | |
13 | 31 | | |
14 | 32 | | |
| 33 | + | |
15 | 34 | | |
16 | | - | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
17 | 40 | | |
18 | 41 | | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
19 | 65 | | |
20 | 66 | | |
21 | 67 | | |
22 | 68 | | |
23 | 69 | | |
24 | 70 | | |
| 71 | + | |
25 | 72 | | |
26 | 73 | | |
27 | 74 | | |
| |||
43 | 90 | | |
44 | 91 | | |
45 | 92 | | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
46 | 130 | | |
47 | 131 | | |
48 | 132 | | |
| |||
62 | 146 | | |
63 | 147 | | |
64 | 148 | | |
| 149 | + | |
65 | 150 | | |
66 | | - | |
| 151 | + | |
67 | 152 | | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
68 | 156 | | |
69 | | - | |
| 157 | + | |
| 158 | + | |
70 | 159 | | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
71 | 163 | | |
72 | 164 | | |
73 | 165 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
0 commit comments