From 0517768cd32c96e96eb6ff80b23c3a8db284dfa0 Mon Sep 17 00:00:00 2001 From: Caidan Williams Date: Fri, 22 Aug 2025 17:08:47 -0700 Subject: feat: add data-nosnippet attribute to Discover feed for SEO control --- src/view/com/feeds/FeedPage.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx index 9f28743a1..0e7813b7c 100644 --- a/src/view/com/feeds/FeedPage.tsx +++ b/src/view/com/feeds/FeedPage.tsx @@ -6,7 +6,7 @@ import {useLingui} from '@lingui/react' import {type NavigationProp, useNavigation} from '@react-navigation/native' import {useQueryClient} from '@tanstack/react-query' -import {VIDEO_FEED_URIS} from '#/lib/constants' +import {DISCOVER_FEED_URI, VIDEO_FEED_URIS} from '#/lib/constants' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {ComposeIcon2} from '#/lib/icons' import {getRootNavigation, getTabState, TabState} from '#/lib/routes/helpers' @@ -73,6 +73,10 @@ export function FeedPage({ return isNative && _isVideoFeed }, [feedInfo]) + const isDiscoverFeed = useMemo(() => { + return feedInfo.uri === DISCOVER_FEED_URI + }, [feedInfo.uri]) + useEffect(() => { if (isPageFocused) { setHomeBadge(hasNew) @@ -128,7 +132,7 @@ export function FeedPage({ const shouldPrefetch = isNative && isPageAdjacent return ( - + Date: Fri, 22 Aug 2025 18:25:35 -0700 Subject: feat: prevent search engines from indexing Discover feed content as page descriptions --- src/view/com/feeds/FeedPage.tsx | 81 ++++++++++++++++++---------------- src/view/com/util/NoSnippetWrapper.tsx | 29 ++++++++++++ 2 files changed, 72 insertions(+), 38 deletions(-) create mode 100644 src/view/com/util/NoSnippetWrapper.tsx (limited to 'src') diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx index 0e7813b7c..26c28729c 100644 --- a/src/view/com/feeds/FeedPage.tsx +++ b/src/view/com/feeds/FeedPage.tsx @@ -29,6 +29,7 @@ import {FAB} from '../util/fab/FAB' import {type ListMethods} from '../util/List' import {LoadLatestBtn} from '../util/load-latest/LoadLatestBtn' import {MainScrollProvider} from '../util/MainScrollProvider' +import {NoSnippetWrapper} from '../util/NoSnippetWrapper' const POLL_FREQ = 60e3 // 60sec @@ -132,45 +133,49 @@ export function FeedPage({ const shouldPrefetch = isNative && isPageAdjacent return ( - - - - + + + + + + + {(isScrolledDown || hasNew) && ( + - - - {(isScrolledDown || hasNew) && ( - - )} + )} - {hasSession && ( - } - accessibilityRole="button" - accessibilityLabel={_(msg({message: `New post`, context: 'action'}))} - accessibilityHint="" - /> - )} - + {hasSession && ( + } + accessibilityRole="button" + accessibilityLabel={_( + msg({message: `New post`, context: 'action'}), + )} + accessibilityHint="" + /> + )} + + ) } diff --git a/src/view/com/util/NoSnippetWrapper.tsx b/src/view/com/util/NoSnippetWrapper.tsx new file mode 100644 index 000000000..fcf658249 --- /dev/null +++ b/src/view/com/util/NoSnippetWrapper.tsx @@ -0,0 +1,29 @@ +import {type ViewProps} from 'react-native' +// @ts-expect-error untyped +import {unstable_createElement} from 'react-native-web' + +import {isWeb} from '#/platform/detection' + +interface Props extends ViewProps { + enabled: boolean +} + +/** + * NoSnippetWrapper prevents search engines from displaying snippets of its content. + * + * If running on web and enabled, wraps children in a
with data-nosnippet attribute. + * Otherwise, renders children directly. + * + * @param enabled - Whether to apply the data-nosnippet attribute. + * @param viewProps - Additional props for the wrapper element. + */ +export function NoSnippetWrapper({enabled, ...viewProps}: Props) { + if (isWeb && enabled) { + return unstable_createElement('div', { + ...viewProps, + 'data-nosnippet': '', + }) + } + + return <>{viewProps.children} +} -- cgit 1.4.1 From bd730db03ecf90efc66953f222d5a7a43cdefe2f Mon Sep 17 00:00:00 2001 From: Caidan Williams Date: Tue, 26 Aug 2025 14:07:18 -0700 Subject: refactor(feed): remove NoSnippetWrapper from FeedPage in favor of dataSet attribute Replaces NoSnippetWrapper with a dataSet prop on the root View to control the nosnippet attribute for discover feeds. This simplifies the component structure and improves maintainability by reducing unnecessary wrappers. --- src/view/com/feeds/FeedPage.tsx | 91 +++++++++++++++++----------------- src/view/com/util/NoSnippetWrapper.tsx | 29 ----------- 2 files changed, 46 insertions(+), 74 deletions(-) delete mode 100644 src/view/com/util/NoSnippetWrapper.tsx (limited to 'src') diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx index 26c28729c..3b4812f1c 100644 --- a/src/view/com/feeds/FeedPage.tsx +++ b/src/view/com/feeds/FeedPage.tsx @@ -18,8 +18,11 @@ import {listenSoftReset} from '#/state/events' import {FeedFeedbackProvider, useFeedFeedback} from '#/state/feed-feedback' import {useSetHomeBadge} from '#/state/home-badge' import {type FeedSourceInfo} from '#/state/queries/feed' -import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed' -import {type FeedDescriptor, type FeedParams} from '#/state/queries/post-feed' +import { + type FeedDescriptor, + type FeedParams, + RQKEY as FEED_RQKEY, +} from '#/state/queries/post-feed' import {truncateAndInvalidate} from '#/state/queries/util' import {useSession} from '#/state/session' import {useSetMinimalShellMode} from '#/state/shell' @@ -29,7 +32,6 @@ import {FAB} from '../util/fab/FAB' import {type ListMethods} from '../util/List' import {LoadLatestBtn} from '../util/load-latest/LoadLatestBtn' import {MainScrollProvider} from '../util/MainScrollProvider' -import {NoSnippetWrapper} from '../util/NoSnippetWrapper' const POLL_FREQ = 60e3 // 60sec @@ -133,49 +135,48 @@ export function FeedPage({ const shouldPrefetch = isNative && isPageAdjacent return ( - - - - - - - - {(isScrolledDown || hasNew) && ( - + + + - )} + + + {(isScrolledDown || hasNew) && ( + + )} - {hasSession && ( - } - accessibilityRole="button" - accessibilityLabel={_( - msg({message: `New post`, context: 'action'}), - )} - accessibilityHint="" - /> - )} - - + {hasSession && ( + } + accessibilityRole="button" + accessibilityLabel={_(msg({message: `New post`, context: 'action'}))} + accessibilityHint="" + /> + )} + ) } diff --git a/src/view/com/util/NoSnippetWrapper.tsx b/src/view/com/util/NoSnippetWrapper.tsx deleted file mode 100644 index fcf658249..000000000 --- a/src/view/com/util/NoSnippetWrapper.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import {type ViewProps} from 'react-native' -// @ts-expect-error untyped -import {unstable_createElement} from 'react-native-web' - -import {isWeb} from '#/platform/detection' - -interface Props extends ViewProps { - enabled: boolean -} - -/** - * NoSnippetWrapper prevents search engines from displaying snippets of its content. - * - * If running on web and enabled, wraps children in a
with data-nosnippet attribute. - * Otherwise, renders children directly. - * - * @param enabled - Whether to apply the data-nosnippet attribute. - * @param viewProps - Additional props for the wrapper element. - */ -export function NoSnippetWrapper({enabled, ...viewProps}: Props) { - if (isWeb && enabled) { - return unstable_createElement('div', { - ...viewProps, - 'data-nosnippet': '', - }) - } - - return <>{viewProps.children} -} -- cgit 1.4.1 From 4a1f1efd7642b4e3cbac25e4d4c43efa1435912c Mon Sep 17 00:00:00 2001 From: Caidan Williams Date: Wed, 27 Aug 2025 11:56:01 -0700 Subject: refactor(feed): simplify isDiscoverFeed logic in FeedPage --- src/view/com/feeds/FeedPage.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx index 3b4812f1c..0f93e66e3 100644 --- a/src/view/com/feeds/FeedPage.tsx +++ b/src/view/com/feeds/FeedPage.tsx @@ -76,10 +76,6 @@ export function FeedPage({ return isNative && _isVideoFeed }, [feedInfo]) - const isDiscoverFeed = useMemo(() => { - return feedInfo.uri === DISCOVER_FEED_URI - }, [feedInfo.uri]) - useEffect(() => { if (isPageFocused) { setHomeBadge(hasNew) @@ -134,6 +130,7 @@ export function FeedPage({ }, [scrollToTop, feed, queryClient]) const shouldPrefetch = isNative && isPageAdjacent + const isDiscoverFeed = feedInfo.uri === DISCOVER_FEED_URI return (