@primer/doctocat-nextjs 0.9.1 → 0.10.0-rc.0e425b1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @primer/doctocat-nextjs
2
2
 
3
+ ## 0.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#99](https://github.com/primer/doctocat-nextjs/pull/99) [`1b72c82`](https://github.com/primer/doctocat-nextjs/commit/1b72c8203115a0e1c7bb511b7abe257cc33ab558) Thanks [@rezrah](https://github.com/rezrah)! - Updated dependencies to latest versions.
8
+ - `@primer/react` 38.3.0 → 38.18.0
9
+ - `@primer/octicons-react` 19.15.1 → 19.23.1
10
+ - `@next/mdx` and `next` 16.1.6 → 16.2.2
11
+ - `framer-motion` 12.23.24 → 12.38.0
12
+ - Replaced `Hero.Image` with standalone `Image` from `@primer/react-brand` for compatibility with 0.65.1
13
+
14
+ - [#98](https://github.com/primer/doctocat-nextjs/pull/98) [`a4e4e89`](https://github.com/primer/doctocat-nextjs/commit/a4e4e89d6935250ab6f8ac84d0d2dc8e9f3b5654) Thanks [@rezrah](https://github.com/rezrah)! - Added support for generating [llms.txt](https://llmstxt.org/) at build time. This file will make your site's content easily discoverable by Agentic AI tools like GitHub Copilot.
15
+
16
+ To enable this feature, create `app/llms.txt/route.ts`:
17
+
18
+ ```ts
19
+ import {generateLLMsTxt} from '@primer/doctocat-nextjs/llms'
20
+
21
+ export const dynamic = 'force-static'
22
+
23
+ export async function GET() {
24
+ const content = await generateLLMsTxt()
25
+
26
+ return new Response(content, {
27
+ headers: {'Content-Type': 'text/plain; charset=utf-8'},
28
+ })
29
+ }
30
+ ```
31
+
32
+ Important: Ensure that `title`, `description` and `keywords` fields are populated in your content's frontmatter.
33
+
3
34
  ## 0.9.1
4
35
 
5
36
  ### Patch Changes
@@ -13,8 +13,8 @@ import {
13
13
  ButtonGroup,
14
14
  ThemeProvider as BrandThemeProvider,
15
15
  Button,
16
- Hero,
17
16
  Heading,
17
+ Image,
18
18
  Stack,
19
19
  Text,
20
20
  } from '@primer/react-brand'
@@ -201,7 +201,7 @@ export function Theme({pageMap, children}: ThemeProps) {
201
201
  )}
202
202
  {activeMetadata.image && (
203
203
  <div className={styles.HeroImageWrapper}>
204
- <Hero.Image src={activeMetadata.image} alt={activeMetadata['image-alt']} />
204
+ <Image src={activeMetadata.image} alt={activeMetadata['image-alt']} />
205
205
  </div>
206
206
  )}
207
207
  {activeMetadata['action-1-text'] && (
package/llms.ts ADDED
@@ -0,0 +1,70 @@
1
+ import {getPageMap} from 'nextra/page-map'
2
+ import type {PageMapItem, MdxFile} from 'nextra'
3
+ import {hasChildren} from './helpers/hasChildren'
4
+
5
+ function isMdxFile(item: PageMapItem): item is MdxFile {
6
+ return 'route' in item && 'name' in item && !('children' in item) && !('data' in item)
7
+ }
8
+
9
+ function getTitle(item: MdxFile): string {
10
+ const title = (item.frontMatter?.title as string) || item.name
11
+ const tabLabel = item.frontMatter?.['tab-label'] as string | undefined
12
+ return tabLabel ? `${title} - ${tabLabel}` : title
13
+ }
14
+
15
+ function getDescription(item: MdxFile): string | undefined {
16
+ return item.frontMatter?.description as string | undefined
17
+ }
18
+
19
+ function getKeywords(item: MdxFile): string[] | undefined {
20
+ const keywords = item.frontMatter?.keywords
21
+ return Array.isArray(keywords) && keywords.length > 0 ? keywords : undefined
22
+ }
23
+
24
+ function getPages(items: PageMapItem[]): MdxFile[] {
25
+ const pages: MdxFile[] = []
26
+ for (const item of items) {
27
+ if (isMdxFile(item)) {
28
+ pages.push(item)
29
+ } else if (hasChildren(item)) {
30
+ pages.push(...getPages(item.children))
31
+ }
32
+ }
33
+ return pages
34
+ }
35
+
36
+ export async function generateLLMsTxt(): Promise<string> {
37
+ const pageMap = await getPageMap()
38
+ const pages = getPages(pageMap)
39
+ const basePath = process.env.NEXT_PUBLIC_DOCTOCAT_BASE_PATH || ''
40
+
41
+ // use homepage to auto-infer site title and descriptions. most users should have filled these out.
42
+ const homepage = pages.find(page => page.route === '/')
43
+ const title = (homepage?.frontMatter?.title as string) || process.env.NEXT_PUBLIC_SITE_TITLE || 'Documentation'
44
+ const description = (homepage?.frontMatter?.description as string) || undefined
45
+
46
+ const lines: string[] = [`# ${title}`, '']
47
+
48
+ if (description) {
49
+ lines.push(`> ${description}`, '')
50
+ }
51
+
52
+ lines.push('## Pages', '')
53
+
54
+ // start adding all sub pages
55
+ for (const page of pages) {
56
+ const pageTitle = getTitle(page)
57
+ const pageDesc = getDescription(page)
58
+ const keywords = getKeywords(page)
59
+ const route = `${basePath}${page.route || '/'}`
60
+
61
+ let entry = `- [${pageTitle}](${route})`
62
+ if (pageDesc) entry += `: ${pageDesc}`
63
+ if (keywords) entry += ` (${keywords.join(', ')})`
64
+
65
+ lines.push(entry)
66
+ }
67
+
68
+ lines.push('')
69
+ return lines.join('\n')
70
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/doctocat-nextjs",
3
- "version": "0.9.1",
3
+ "version": "0.10.0-rc.0e425b1",
4
4
  "description": "A Next.js theme for building Primer documentation sites",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -25,33 +25,33 @@
25
25
  "react-dom": ">=18.0.0 <20.0.0"
26
26
  },
27
27
  "dependencies": {
28
- "@next/mdx": "16.1.6",
29
- "@primer/octicons-react": "19.15.1",
30
- "@primer/react": "^38.3.0",
28
+ "@next/mdx": "16.2.2",
29
+ "@primer/octicons-react": "19.23.1",
30
+ "@primer/react": "^38.18.0",
31
31
  "@types/lodash.debounce": "^4.0.9",
32
- "framer-motion": "12.23.24",
32
+ "framer-motion": "12.38.0",
33
33
  "lodash.debounce": "^4.0.8",
34
34
  "nextra": "4.6.1",
35
- "react-focus-on": "^3.10.0",
36
- "react-is": "^19.2.0",
35
+ "react-focus-on": "^3.10.2",
36
+ "react-is": "^19.2.4",
37
37
  "react-live": "^4.1.8"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@github/prettier-config": "^0.0.6",
41
- "@testing-library/dom": "^10.4.0",
42
- "@testing-library/jest-dom": "^6.6.3",
43
- "@testing-library/react": "^16.1.0",
44
- "@testing-library/user-event": "^14.5.2",
45
- "@types/node": "^20.19.0",
46
- "@types/react": "^19.2.7",
41
+ "@testing-library/dom": "^10.4.1",
42
+ "@testing-library/jest-dom": "^6.9.1",
43
+ "@testing-library/react": "^16.3.2",
44
+ "@testing-library/user-event": "^14.6.1",
45
+ "@types/node": "^24.12.0",
46
+ "@types/react": "^19.2.14",
47
47
  "@types/react-dom": "^19.2.3",
48
48
  "@vitejs/plugin-react": "^4.3.3",
49
- "@vitest/coverage-v8": "^3.2.4",
50
- "@vitest/ui": "^3.2.4",
49
+ "@vitest/coverage-v8": "^4.1.2",
50
+ "@vitest/ui": "^4.1.2",
51
51
  "clsx": "2.1.1",
52
- "jsdom": "^26.0.1",
53
- "next": "16.1.6",
52
+ "jsdom": "^29.0.1",
53
+ "next": "16.2.2",
54
54
  "styled-components": "5.3.11",
55
- "vitest": "^3.2.4"
55
+ "vitest": "^4.1.2"
56
56
  }
57
57
  }