From 4c19014dcd1ad9fb5864646ac71978e9efcc1f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Fri, 13 Sep 2024 13:52:15 +0200 Subject: [PATCH] Prevent robots indexation for pages where it's disabled (#2464) --- .changeset/thick-dogs-bake.md | 5 ++ .github/workflows/ci.yaml | 6 +++ bun.lockb | Bin 674336 -> 673984 bytes packages/gitbook/e2e/pages.spec.ts | 51 ++++++++++++++++++ packages/gitbook/package.json | 2 +- .../(content)/[[...pathname]]/page.tsx | 7 ++- .../src/app/(space)/(content)/layout.tsx | 4 +- .../app/(space)/(core)/robots.txt/route.ts | 4 +- .../app/(space)/(core)/sitemap.xml/route.ts | 13 +++-- packages/gitbook/src/lib/seo.ts | 31 ++++++++++- packages/gitbook/src/middleware.ts | 9 ++++ packages/react-contentkit/package.json | 2 +- 12 files changed, 122 insertions(+), 12 deletions(-) create mode 100644 .changeset/thick-dogs-bake.md diff --git a/.changeset/thick-dogs-bake.md b/.changeset/thick-dogs-bake.md new file mode 100644 index 000000000..b26fb4884 --- /dev/null +++ b/.changeset/thick-dogs-bake.md @@ -0,0 +1,5 @@ +--- +'gitbook': minor +--- + +Prevent search indexation for pages where it's configured as disabled diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9cf0820bc..21d203291 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -93,6 +93,12 @@ jobs: env: BASE_URL: ${{needs.deploy.outputs.deployment_url}} ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }} + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-test-results + path: packages/gitbook/test-results/ + retention-days: 3 pagespeed-testing: runs-on: ubuntu-latest name: PageSpeed Testing diff --git a/bun.lockb b/bun.lockb index 342942d7dad954feaa623a275c46a94369468d07..62159121efedc9f9a0e0e07641b1f9fce89b5250 100755 GIT binary patch delta 55163 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 G&i@BucpvZp delta 55690 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 { + const metaRobots = page.locator('meta[name="robots"]'); + await expect(metaRobots).toHaveAttribute('content', 'index, follow'); + }, + }, + { + name: `Don't index noIndex`, + url: 'page-options/page-no-index?x-gitbook-search-indexation=true', + screenshot: false, + run: async (page) => { + const metaRobots = page.locator('meta[name="robots"]'); + await expect(metaRobots).toHaveAttribute('content', 'noindex, nofollow'); + }, + }, + { + name: `Don't index descendant of noIndex`, + url: 'page-options/page-no-index/descendant-of-page-no-index?x-gitbook-search-indexation=true', + screenshot: false, + run: async (page) => { + const metaRobots = page.locator('meta[name="robots"]'); + await expect(metaRobots).toHaveAttribute('content', 'noindex, nofollow'); + }, + }, + { + name: `Don't index noRobotsIndex`, + url: 'page-options/page-no-robots-index?x-gitbook-search-indexation=true', + screenshot: false, + run: async (page) => { + const metaRobots = page.locator('meta[name="robots"]'); + await expect(metaRobots).toHaveAttribute('content', 'noindex, nofollow'); + }, + }, + { + name: `Don't index descendant of noRobotsIndex`, + url: 'page-options/page-no-robots-index/descendant-of-page-no-robots-index?x-gitbook-search-indexation=true', + screenshot: false, + run: async (page) => { + const metaRobots = page.locator('meta[name="robots"]'); + await expect(metaRobots).toHaveAttribute('content', 'noindex, nofollow'); + }, + }, + ], + }, ]; for (const testCase of testCases) { diff --git a/packages/gitbook/package.json b/packages/gitbook/package.json index c1b4a1ac1..a594313d0 100644 --- a/packages/gitbook/package.json +++ b/packages/gitbook/package.json @@ -15,7 +15,7 @@ "copy:icons": "gitbook-icons ./public/~gitbook/static/icons" }, "dependencies": { - "@gitbook/api": "^0.60.0", + "@gitbook/api": "0.60.0", "@gitbook/icons": "workspace:*", "@gitbook/react-math": "workspace:*", "@gitbook/react-openapi": "workspace:*", diff --git a/packages/gitbook/src/app/(space)/(content)/[[...pathname]]/page.tsx b/packages/gitbook/src/app/(space)/(content)/[[...pathname]]/page.tsx index 947d84693..b5ab1424e 100644 --- a/packages/gitbook/src/app/(space)/(content)/[[...pathname]]/page.tsx +++ b/packages/gitbook/src/app/(space)/(content)/[[...pathname]]/page.tsx @@ -8,6 +8,7 @@ import { PageBody, PageCover } from '@/components/PageBody'; import { PageHrefContext, absoluteHref, pageHref } from '@/lib/links'; import { getPagePath, resolveFirstDocument } from '@/lib/pages'; import { ContentRefContext } from '@/lib/references'; +import { isSpaceIndexable, isPageIndexable } from '@/lib/seo'; import { tcls } from '@/lib/tailwind'; import { getContentTitle } from '@/lib/utils'; @@ -129,7 +130,7 @@ export async function generateMetadata({ params: PagePathParams; searchParams: { fallback?: string }; }): Promise { - const { space, pages, page, customization, parent } = await getPageDataWithFallback({ + const { space, pages, page, customization, parent, ancestors } = await getPageDataWithFallback({ pagePathParams: params, searchParams, }); @@ -152,6 +153,10 @@ export async function generateMetadata({ absoluteHref(`~gitbook/ogimage/${page.id}`, true), ], }, + robots: + isSpaceIndexable({ space, parent }) && isPageIndexable(ancestors, page) + ? 'index, follow' + : 'noindex, nofollow', }; } diff --git a/packages/gitbook/src/app/(space)/(content)/layout.tsx b/packages/gitbook/src/app/(space)/(content)/layout.tsx index 301f034bc..5114af386 100644 --- a/packages/gitbook/src/app/(space)/(content)/layout.tsx +++ b/packages/gitbook/src/app/(space)/(content)/layout.tsx @@ -13,7 +13,7 @@ import { assetsDomain } from '@/lib/assets'; import { buildVersion } from '@/lib/build'; import { getContentSecurityPolicyNonce } from '@/lib/csp'; import { absoluteHref, baseUrl } from '@/lib/links'; -import { shouldIndexSpace } from '@/lib/seo'; +import { isSpaceIndexable } from '@/lib/seo'; import { getContentTitle } from '@/lib/utils'; import { ClientContexts } from './ClientContexts'; @@ -133,7 +133,7 @@ export async function generateMetadata(): Promise { }, ], }, - robots: shouldIndexSpace({ space, parent }) ? 'index, follow' : 'noindex, nofollow', + robots: isSpaceIndexable({ space, parent }) ? 'index, follow' : 'noindex, nofollow', }; } diff --git a/packages/gitbook/src/app/(space)/(core)/robots.txt/route.ts b/packages/gitbook/src/app/(space)/(core)/robots.txt/route.ts index 4b4e9f6df..dc3d6aa96 100644 --- a/packages/gitbook/src/app/(space)/(core)/robots.txt/route.ts +++ b/packages/gitbook/src/app/(space)/(core)/robots.txt/route.ts @@ -3,7 +3,7 @@ import { NextRequest } from 'next/server'; import { getCollection, getSite, getSpace } from '@/lib/api'; import { absoluteHref } from '@/lib/links'; -import { shouldIndexSpace } from '@/lib/seo'; +import { isSpaceIndexable } from '@/lib/seo'; import { getContentPointer } from '../../fetch'; @@ -28,7 +28,7 @@ export async function GET(req: NextRequest) { const lines = [ `User-agent: *`, 'Disallow: /~gitbook/', - ...(shouldIndexSpace({ space, parent }) + ...(isSpaceIndexable({ space, parent }) ? [`Allow: /`, `Sitemap: ${absoluteHref(`/sitemap.xml`, true)}`] : [`Disallow: /`]), ]; diff --git a/packages/gitbook/src/app/(space)/(core)/sitemap.xml/route.ts b/packages/gitbook/src/app/(space)/(core)/sitemap.xml/route.ts index 398e2af69..f0a23df27 100644 --- a/packages/gitbook/src/app/(space)/(core)/sitemap.xml/route.ts +++ b/packages/gitbook/src/app/(space)/(core)/sitemap.xml/route.ts @@ -5,6 +5,7 @@ import { NextRequest } from 'next/server'; import { getSpaceContentData } from '@/lib/api'; import { absoluteHref } from '@/lib/links'; import { getPagePath } from '@/lib/pages'; +import { isPageIndexable } from '@/lib/seo'; import { getContentPointer } from '../../fetch'; @@ -19,7 +20,8 @@ export async function GET(req: NextRequest) { pointer, 'siteId' in pointer ? pointer.siteShareKey : undefined, ); - const pages = flattenPages(rootPages, (page) => !page.hidden); + + const pages = flattenPages(rootPages, (page) => !page.hidden && isPageIndexable([], page)); const urls = pages.map(({ page, depth }) => { // Decay priority with depth const priority = Math.pow(2, -0.25 * depth); @@ -72,14 +74,19 @@ type FlatPageEntry = { page: RevisionPageDocument; depth: number }; function flattenPages( rootPags: RevisionPage[], - filter: (page: RevisionPageDocument) => boolean, + filter: (page: RevisionPageDocument | RevisionPageGroup) => boolean, ): FlatPageEntry[] { const flattenPage = ( page: RevisionPageDocument | RevisionPageGroup, depth: number, ): FlatPageEntry[] => { + const allowed = filter(page); + if (!allowed) { + return []; + } + return [ - ...(page.type === 'document' && filter(page) ? [{ page, depth }] : []), + ...(page.type === 'document' ? [{ page, depth }] : []), ...page.pages.flatMap((child) => child.type === 'link' ? [] : flattenPage(child, depth + 1), ), diff --git a/packages/gitbook/src/lib/seo.ts b/packages/gitbook/src/lib/seo.ts index 43fdbfb9d..1eb84ebbb 100644 --- a/packages/gitbook/src/lib/seo.ts +++ b/packages/gitbook/src/lib/seo.ts @@ -1,10 +1,37 @@ -import { Collection, ContentVisibility, Site, SiteVisibility, Space } from '@gitbook/api'; +import { + Collection, + ContentVisibility, + RevisionPageDocument, + RevisionPageGroup, + Site, + SiteVisibility, + Space, +} from '@gitbook/api'; import { headers } from 'next/headers'; +/** + * Return true if a page is indexable in search. + */ +export function isPageIndexable( + ancestors: Array, + page: RevisionPageDocument | RevisionPageGroup, +): boolean { + // @ts-ignore - noIndex and noRobotsIndex are not in the type + // until we fix the deprecated APIs + return ( + // @ts-ignore + !page.noIndex && + // @ts-ignore + !page.noRobotsIndex && + // @ts-ignore + ancestors.every((ancestor) => !ancestor.noIndex && !ancestor.noRobotsIndex) + ); +} + /** * Return true if a space should be indexed by search engines. */ -export function shouldIndexSpace({ +export function isSpaceIndexable({ space, parent, }: { diff --git a/packages/gitbook/src/middleware.ts b/packages/gitbook/src/middleware.ts index aeb368632..9ba3e06ef 100644 --- a/packages/gitbook/src/middleware.ts +++ b/packages/gitbook/src/middleware.ts @@ -216,6 +216,15 @@ export async function middleware(request: NextRequest) { } } + // For tests, we make it possible to enable search indexation + // using a query parameter. + const xGitBookSearchIndexation = + headers.get('x-gitbook-search-indexation') ?? + url.searchParams.has('x-gitbook-search-indexation'); + if (xGitBookSearchIndexation) { + headers.set('x-gitbook-search-indexation', 'true'); + } + if (resolved.revision) { headers.set('x-gitbook-content-revision', resolved.revision); } diff --git a/packages/react-contentkit/package.json b/packages/react-contentkit/package.json index 69ea324d2..b2c914c01 100644 --- a/packages/react-contentkit/package.json +++ b/packages/react-contentkit/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "classnames": "^2.5.1", - "@gitbook/api": "^0.58.0", + "@gitbook/api": "0.60.0", "assert-never": "^1.2.1" }, "peerDependencies": {