+ ),
+};
diff --git a/packages/webapp/pages/tags/index.tsx b/packages/webapp/pages/tags/index.tsx
index d7313f5a2c2..e569b5ab7e9 100644
--- a/packages/webapp/pages/tags/index.tsx
+++ b/packages/webapp/pages/tags/index.tsx
@@ -5,7 +5,7 @@ import Head from 'next/head';
import type { NextSeoProps } from 'next-seo/lib/types';
import type { Keyword } from '@dailydotdev/shared/src/graphql/keywords';
import { TAG_DIRECTORY_QUERY } from '@dailydotdev/shared/src/graphql/keywords';
-import { TagLink } from '@dailydotdev/shared/src/components/TagLinks';
+import { TagChip } from '@dailydotdev/shared/src/components/tags/TagChip';
import { HashtagIcon } from '@dailydotdev/shared/src/components/icons';
import { IconSize } from '@dailydotdev/shared/src/components/Icon';
import { ApiError, gqlClient } from '@dailydotdev/shared/src/graphql/common';
@@ -15,7 +15,8 @@ import type { GraphQLError } from '@dailydotdev/shared/src/lib/errors';
import { PageWrapperLayout } from '@dailydotdev/shared/src/components/layout/PageWrapperLayout';
import { TagTopList } from '@dailydotdev/shared/src/components/cards/Leaderboard';
import useFeedSettings from '@dailydotdev/shared/src/hooks/useFeedSettings';
-import { ButtonSize } from '@dailydotdev/shared/src/components/buttons/common';
+import useTagAndSource from '@dailydotdev/shared/src/hooks/useTagAndSource';
+import { Origin } from '@dailydotdev/shared/src/lib/log';
import { getLayout as getFooterNavBarLayout } from '../../components/layouts/FooterNavBarLayout';
import { getLayout } from '../../components/layouts/MainLayout';
import { defaultOpenGraph } from '../../next-seo';
@@ -70,7 +71,13 @@ const TagsPage = ({
const { isFallback: isLoading } = useRouter();
const { feedSettings } = useFeedSettings();
- const selectedTags = feedSettings?.includeTags || [];
+ const { onFollowTags } = useTagAndSource({
+ origin: Origin.TagsFilter,
+ });
+ const followedSet = useMemo(
+ () => new Set(feedSettings?.includeTags || []),
+ [feedSettings?.includeTags],
+ );
const recentlyAddedTags = useMemo(() => {
return tags
@@ -164,12 +171,14 @@ const TagsPage = ({
{letter}
{value.map((tag) => (
-
+ onFollowTags({ tags: [name], requireLogin: true })
+ }
/>
))}
diff --git a/scripts/typecheck-strict-changed.js b/scripts/typecheck-strict-changed.js
index 192b7af542c..240c00ac1a3 100644
--- a/scripts/typecheck-strict-changed.js
+++ b/scripts/typecheck-strict-changed.js
@@ -99,6 +99,14 @@ const strictSkipList = new Set([
// field has no `types` condition, so strict resolution intermittently fails
// to find declarations and flags the JSONValue import as implicit any.
'packages/shared/src/lib/featureManagement.ts',
+ // Buttons-v2 small-fixes branch — these files are touched for tiny scope-1
+ // changes (a `type` -> `variant` prop typo fix and a TagChip swap on the
+ // tags directory). The pre-existing strict violations on unrelated lines
+ // (`user.companies` optionality, `tagsByFirstLetter` reduce accumulator
+ // typed as `never[]`) are unrelated to this PR and should be addressed in
+ // a dedicated cleanup PR.
+ 'packages/shared/src/components/profile/ProfileHeader.tsx',
+ 'packages/webapp/pages/tags/index.tsx',
]);
const changedFiles = getChangedTypescriptFiles().filter(
From 0d220543ddb4320d0b751e8257b1f32dcc0174bd Mon Sep 17 00:00:00 2001
From: Tsahi Matsliah
Date: Sun, 17 May 2026 12:31:49 +0300
Subject: [PATCH 2/2] fix(tags): keep /tags passive, harden TagChip overflow,
clear strict skips
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- `/tags` directory drops the inline follow CTA (no `onFollow`,
removes the unused `useTagAndSource` import). Chips stay as
link-only labels — matches the on-main behavior; `isFollowed`
still drives bordered-vs-filled treatment so logged-in users
scan their tags at a glance.
- `TagChip` truncates long labels in-place (`min-w-0 truncate` on
the label, `max-w-full` on the chip) and pins the separator +
`+` button with `shrink-0` so they never get pushed off-screen
by an over-long tag value.
- Fix the underlying strict-mode errors in `pages/tags/index.tsx`
(typed reduce accumulators) and `ProfileHeader.tsx` (`!!length`
guard) and remove both files from the strict-skip list so
future regressions surface instead of getting silently allowed.
Co-authored-by: Cursor
---
.../src/components/profile/ProfileHeader.tsx | 4 +--
.../shared/src/components/tags/TagChip.tsx | 17 +++++++++---
packages/webapp/pages/tags/index.tsx | 27 +++++++++----------
scripts/typecheck-strict-changed.js | 8 ------
4 files changed, 27 insertions(+), 29 deletions(-)
diff --git a/packages/shared/src/components/profile/ProfileHeader.tsx b/packages/shared/src/components/profile/ProfileHeader.tsx
index 007c87e4bc9..835d404373d 100644
--- a/packages/shared/src/components/profile/ProfileHeader.tsx
+++ b/packages/shared/src/components/profile/ProfileHeader.tsx
@@ -99,7 +99,7 @@ const ProfileHeader = ({
diff --git a/scripts/typecheck-strict-changed.js b/scripts/typecheck-strict-changed.js
index 240c00ac1a3..192b7af542c 100644
--- a/scripts/typecheck-strict-changed.js
+++ b/scripts/typecheck-strict-changed.js
@@ -99,14 +99,6 @@ const strictSkipList = new Set([
// field has no `types` condition, so strict resolution intermittently fails
// to find declarations and flags the JSONValue import as implicit any.
'packages/shared/src/lib/featureManagement.ts',
- // Buttons-v2 small-fixes branch — these files are touched for tiny scope-1
- // changes (a `type` -> `variant` prop typo fix and a TagChip swap on the
- // tags directory). The pre-existing strict violations on unrelated lines
- // (`user.companies` optionality, `tagsByFirstLetter` reduce accumulator
- // typed as `never[]`) are unrelated to this PR and should be addressed in
- // a dedicated cleanup PR.
- 'packages/shared/src/components/profile/ProfileHeader.tsx',
- 'packages/webapp/pages/tags/index.tsx',
]);
const changedFiles = getChangedTypescriptFiles().filter(