@primer/doctocat-nextjs 0.0.0-20250904115752 → 0.0.0-20250904133213

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,16 +1,16 @@
1
1
  # @primer/doctocat-nextjs
2
2
 
3
- ## 0.0.0-20250904115752
3
+ ## 0.0.0-20250904133213
4
4
 
5
5
  ### Patch Changes
6
6
 
7
7
  - Fake entry to force publishing
8
8
 
9
- ## 0.0.0-20250904115750
9
+ ## 0.0.0-20250904133211
10
10
 
11
11
  ### Minor Changes
12
12
 
13
- - [`84ff648`](https://github.com/primer/doctocat-nextjs/commit/84ff648a8248712d61e13a7e6432ab2ab8e07435) Thanks [@rezrah](https://github.com/rezrah)! - Updated Next.js compatibility to v15.5.x, Nextra to v4, and fix React code block rendering
13
+ - [#65](https://github.com/primer/doctocat-nextjs/pull/65) [`84ff648`](https://github.com/primer/doctocat-nextjs/commit/84ff648a8248712d61e13a7e6432ab2ab8e07435) Thanks [@rezrah](https://github.com/rezrah)! - Updated Next.js compatibility to v15.5.x, Nextra to v4, and fix React code block rendering
14
14
 
15
15
  - **Next.js v15.5.2**: Upgraded to latest stable version across all workspaces
16
16
  - **Nextra v4 compatibility**: Updated type definitions for `ReactNode` titles
@@ -37,26 +37,40 @@ export function CodeBlock(props: CodeBlockProps) {
37
37
  // Next.js v15.4+ will lazy render components on the server, which prevents us from
38
38
  // sending usable React nodes to the ReactCodeBlock component.
39
39
  // Workaround is to convert the code snippets to string on the client and pass to react-live.
40
- try {
41
- const childrenAsString = renderToStaticMarkup(<>{props.children}</>)
42
-
43
- const textContent = childrenAsString.replace(/<[^>]*>/g, '')
44
-
45
- // Restore escaped chars
46
- const decodedText = textContent
47
- .replace(/&lt;/g, '<')
48
- .replace(/&gt;/g, '>')
49
- .replace(/&quot;/g, '"')
50
- .replace(/&#x27;/g, "'")
51
- .replace(/&amp;/g, '&')
52
-
53
- return <ReactCodeBlock {...props} code={decodedText} />
54
- } catch (error) {
55
- // eslint-disable-next-line no-console
56
- console.log('Error extracting code snippet. Forwarding children directly:', error)
57
- // Fallback to original children-based approach
58
- return <ReactCodeBlock {...props} />
40
+
41
+ // suppresses compilation warnings
42
+ if (typeof window !== 'undefined') {
43
+ try {
44
+ const childrenAsString = renderToStaticMarkup(<>{props.children}</>)
45
+
46
+ // Extract text content using browser's HTML parser (immune to regex bypass attacks)
47
+ const cleanHtmlTag = (str: string): string => {
48
+ const parser = new DOMParser()
49
+ const doc = parser.parseFromString(str, 'text/html')
50
+ return doc.body.textContent || doc.body.innerText || ''
51
+ }
52
+
53
+ const textContent = cleanHtmlTag(childrenAsString)
54
+
55
+ // Restore escaped chars
56
+ const decodedText = textContent
57
+ .replace(/&lt;/g, '<')
58
+ .replace(/&gt;/g, '>')
59
+ .replace(/&quot;/g, '"')
60
+ .replace(/&#x27;/g, "'")
61
+ .replace(/&amp;/g, '&')
62
+
63
+ return <ReactCodeBlock {...props} code={decodedText} />
64
+ } catch (error) {
65
+ // eslint-disable-next-line no-console
66
+ console.log('Error extracting code snippet. Forwarding children directly:', error)
67
+ // Fallback to original children-based approach
68
+ return <ReactCodeBlock {...props} />
69
+ }
59
70
  }
71
+
72
+ // During SSR/build, use children-based approach
73
+ return <ReactCodeBlock {...props} />
60
74
  }
61
75
 
62
76
  return <Pre>{props.children}</Pre>
@@ -1,5 +1,6 @@
1
1
  import {DocsItem, FrontMatter} from '../../../types'
2
2
  import {RelatedContentLink} from './RelatedContentLinks'
3
+ import React from 'react'
3
4
 
4
5
  type GetRelatedPages = (
5
6
  route: string,
@@ -58,7 +59,17 @@ export const getRelatedPages: GetRelatedPages = (route, activeMetadata, flatDocs
58
59
  }
59
60
 
60
61
  function titleToString(title: React.ReactNode): string {
61
- if (typeof title === 'string') return title
62
- if (typeof title === 'number') return title.toString()
63
- return ''
62
+ const children = React.Children.toArray(title)
63
+
64
+ return children
65
+ .map(child => {
66
+ if (typeof child === 'string' || typeof child === 'number') {
67
+ return child.toString()
68
+ }
69
+ if (React.isValidElement(child) && child.props.children) {
70
+ return titleToString(child.props.children)
71
+ }
72
+ return ''
73
+ })
74
+ .join('')
64
75
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/doctocat-nextjs",
3
- "version": "0.0.0-20250904115752",
3
+ "version": "0.0.0-20250904133213",
4
4
  "description": "A Next.js theme for building Primer documentation sites",
5
5
  "main": "index.js",
6
6
  "type": "module",