From 6ddc268b91d990da6ef754323310227690378556 Mon Sep 17 00:00:00 2001 From: Caidan Williams 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