diff options
author | jim <310223+jimmylee@users.noreply.github.com> | 2025-08-25 23:07:00 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-25 23:07:00 -0700 |
commit | d1aab5698275e8ff0d0ce15d73f8844c0f8db598 (patch) | |
tree | 5e8fbc681bba14bda0e25e645b882d9dbbbea143 | |
parent | bb1eab41c6b7a967a91ac72c19e6b61d2b476592 (diff) | |
parent | eb45154823323b0c7ecbd49b5896118b106cd762 (diff) | |
download | voidsky-d1aab5698275e8ff0d0ce15d73f8844c0f8db598.tar.zst |
Merge pull request #8900 from internet-development/caidanw/app-1413-clean-up-canonical-urls
feat: implement canonical URL filter to clean parameters for SEO
-rw-r--r-- | bskyweb/cmd/bskyweb/filters.go | 28 | ||||
-rw-r--r-- | bskyweb/cmd/bskyweb/filters_test.go | 61 | ||||
-rw-r--r-- | bskyweb/templates/post.html | 2 | ||||
-rw-r--r-- | bskyweb/templates/profile.html | 2 |
4 files changed, 91 insertions, 2 deletions
diff --git a/bskyweb/cmd/bskyweb/filters.go b/bskyweb/cmd/bskyweb/filters.go new file mode 100644 index 000000000..a92cc606b --- /dev/null +++ b/bskyweb/cmd/bskyweb/filters.go @@ -0,0 +1,28 @@ +package main + +import ( + "net/url" + + "github.com/flosch/pongo2/v6" +) + +func init() { + pongo2.RegisterFilter("canonicalize_url", filterCanonicalizeURL) +} + +func filterCanonicalizeURL(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { + urlStr := in.String() + + parsedURL, err := url.Parse(urlStr) + if err != nil { + // If parsing fails, return the original URL + return in, nil + } + + // Remove query parameters and fragment + parsedURL.RawQuery = "" + parsedURL.Fragment = "" + + // Return the cleaned URL + return pongo2.AsValue(parsedURL.String()), nil +} diff --git a/bskyweb/cmd/bskyweb/filters_test.go b/bskyweb/cmd/bskyweb/filters_test.go new file mode 100644 index 000000000..a63ad0317 --- /dev/null +++ b/bskyweb/cmd/bskyweb/filters_test.go @@ -0,0 +1,61 @@ +package main + +import ( + "testing" + + "github.com/flosch/pongo2/v6" +) + +func TestCanonicalizeURLFilter(t *testing.T) { + tests := []struct { + name string + input string + expected string + }{ + { + name: "clean URL", + input: "https://bsky.app/profile/user", + expected: "https://bsky.app/profile/user", + }, + { + name: "URL with query params", + input: "https://bsky.app/profile/user?utm_source=test", + expected: "https://bsky.app/profile/user", + }, + { + name: "URL with multiple params", + input: "https://bsky.app/profile/user?utm_source=twitter&utm_campaign=test", + expected: "https://bsky.app/profile/user", + }, + { + name: "URL with fragment", + input: "https://bsky.app/profile/user#section", + expected: "https://bsky.app/profile/user", + }, + { + name: "URL with both params and fragment", + input: "https://bsky.app/profile/user?param=1#section", + expected: "https://bsky.app/profile/user", + }, + { + name: "malformed URL", + input: "not-a-url", + expected: "not-a-url", // Should return original on error + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + inputValue := pongo2.AsValue(tt.input) + result, err := filterCanonicalizeURL(inputValue, nil) + if err != nil { + t.Errorf("filterCanonicalizeURL() error = %v", err) + return + } + + if result.String() != tt.expected { + t.Errorf("filterCanonicalizeURL() = %v, want %v", result.String(), tt.expected) + } + }) + } +} diff --git a/bskyweb/templates/post.html b/bskyweb/templates/post.html index 963af2065..1f3f6da4e 100644 --- a/bskyweb/templates/post.html +++ b/bskyweb/templates/post.html @@ -14,7 +14,7 @@ <meta property="profile:username" content="{{ profileView.Handle }}"> {%- if requestURI %} <meta property="og:url" content="{{ requestURI }}"> - <link rel="canonical" href="{{ requestURI }}" /> + <link rel="canonical" href="{{ requestURI|canonicalize_url }}" /> {% endif -%} {%- if postView.Author.DisplayName %} <meta property="og:title" content="{{ postView.Author.DisplayName }} (@{{ postView.Author.Handle }})"> diff --git a/bskyweb/templates/profile.html b/bskyweb/templates/profile.html index af4180dc1..8506a9cff 100644 --- a/bskyweb/templates/profile.html +++ b/bskyweb/templates/profile.html @@ -15,7 +15,7 @@ <meta property="profile:username" content="{{ profileView.Handle }}"> {%- if requestURI %} <meta property="og:url" content="{{ requestURI }}"> - <link rel="canonical" href="{{ requestURI }}" /> + <link rel="canonical" href="{{ requestURI|canonicalize_url }}" /> {% endif -%} {%- if profileView.DisplayName %} <meta property="og:title" content="{{ profileView.DisplayName }} (@{{ profileView.Handle }})"> |