diff --git a/frontend/e2e/profile.spec.ts b/frontend/e2e/profile.spec.ts
index 35c48e9..163a9e1 100644
--- a/frontend/e2e/profile.spec.ts
+++ b/frontend/e2e/profile.spec.ts
@@ -50,6 +50,33 @@ test('Profile link in nav for authed users; landing shows counts', async ({ page
await expect(page.getByTestId('overview-collections')).toBeVisible();
});
+test('Page tags tab reaches the page-tags list on desktop', async ({ page }) => {
+ // Page tags are a first-class Library section on mobile; desktop reaches
+ // them through this profile tab.
+ await stubAuthenticated(page);
+ await page.route('**/api/v1/me/page-tags?*', (route) =>
+ route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify({ items: [], page: { limit: 100, offset: 0, total: 0 } })
+ })
+ );
+ // Registered after the general route so distinct URLs resolve here.
+ await page.route('**/api/v1/me/page-tags/distinct*', (route) =>
+ route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify({ items: [] })
+ })
+ );
+
+ await page.goto('/profile');
+ await expect(page.getByTestId('tab-page-tags')).toBeVisible();
+ await page.getByTestId('tab-page-tags').click();
+ await expect(page).toHaveURL(/\/profile\/page-tags$/);
+ await expect(page.getByTestId('library-page-tags-empty')).toBeVisible();
+});
+
test('Account tab reaches the password form', async ({ page }) => {
await stubAuthenticated(page);
await page.goto('/profile');
diff --git a/frontend/src/routes/profile/+layout.svelte b/frontend/src/routes/profile/+layout.svelte
index 1d1db32..48dc122 100644
--- a/frontend/src/routes/profile/+layout.svelte
+++ b/frontend/src/routes/profile/+layout.svelte
@@ -6,6 +6,7 @@
import KeyRound from '@lucide/svelte/icons/key-round';
import Bookmark from '@lucide/svelte/icons/bookmark';
import FolderOpen from '@lucide/svelte/icons/folder-open';
+ import Tag from '@lucide/svelte/icons/tag';
import History from '@lucide/svelte/icons/history';
let { children } = $props();
@@ -27,6 +28,7 @@
{ href: '/profile/account', label: 'Account', icon: KeyRound, testid: 'tab-account', guestVisible: false },
{ href: '/profile/bookmarks', label: 'Bookmarks', icon: Bookmark, testid: 'tab-bookmarks', guestVisible: false },
{ href: '/profile/collections', label: 'Collections', icon: FolderOpen, testid: 'tab-collections', guestVisible: false },
+ { href: '/profile/page-tags', label: 'Page tags', icon: Tag, testid: 'tab-page-tags', guestVisible: false },
{ href: '/profile/history', label: 'History', icon: History, testid: 'tab-history', guestVisible: false }
];
diff --git a/frontend/src/routes/profile/page-tags/+page.svelte b/frontend/src/routes/profile/page-tags/+page.svelte
new file mode 100644
index 0000000..c9dcbd8
--- /dev/null
+++ b/frontend/src/routes/profile/page-tags/+page.svelte
@@ -0,0 +1,31 @@
+
+
+
+ Couldn't load page tags: {data.error} +
+{:else if !data.authenticated} ++ Sign in to see your page tags. +
+{:else} +