Skip to content

Commit 5ca8e8b

Browse files
committed
Refactor: make more components cross compatible
1 parent 5da0ada commit 5ca8e8b

File tree

4 files changed

+51
-22
lines changed

4 files changed

+51
-22
lines changed

src/components/Layout/Feedback.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use client';
2+
13
/**
24
* Copyright (c) Meta Platforms, Inc. and affiliates.
35
*
@@ -10,14 +12,13 @@
1012
*/
1113

1214
import {useState} from 'react';
13-
import {useRouter} from 'next/router';
15+
import {usePathname} from 'next/navigation';
1416
import cn from 'classnames';
1517

1618
export function Feedback({onSubmit = () => {}}: {onSubmit?: () => void}) {
17-
const {asPath} = useRouter();
18-
const cleanedPath = asPath.split(/[\?\#]/)[0];
19+
const pathname = usePathname();
1920
// Reset on route changes.
20-
return <SendFeedback key={cleanedPath} onSubmit={onSubmit} />;
21+
return <SendFeedback key={pathname} onSubmit={onSubmit} />;
2122
}
2223

2324
const thumbsUpIcon = (

src/components/Layout/Page.tsx

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
* Copyright (c) Facebook, Inc. and its affiliates.
1010
*/
1111

12+
'use client';
13+
1214
import {Suspense} from 'react';
1315
import * as React from 'react';
14-
import {useRouter} from 'next/router';
16+
import {useRouter} from 'next/compat/router';
1517
import {SidebarNav} from './SidebarNav';
1618
import {Footer} from './Footer';
1719
import {Toc} from './Toc';
@@ -28,6 +30,7 @@ import {HomeContent} from './HomeContent';
2830
import {TopNav} from './TopNav';
2931
import cn from 'classnames';
3032
import Head from 'next/head';
33+
import {usePathname} from 'next/navigation';
3134

3235
import(/* webpackPrefetch: true */ '../MDX/CodeBlock/CodeBlock');
3336

@@ -43,6 +46,8 @@ interface PageProps {
4346
};
4447
section: 'learn' | 'reference' | 'community' | 'blog' | 'home' | 'unknown';
4548
languages?: Languages | null;
49+
/** Should this being used with the Next.js App Router? */
50+
appRouter?: boolean;
4651
}
4752

4853
export function Page({
@@ -52,9 +57,14 @@ export function Page({
5257
meta,
5358
section,
5459
languages = null,
60+
appRouter = false,
5561
}: PageProps) {
56-
const {asPath} = useRouter();
57-
const cleanedPath = asPath.split(/[\?\#]/)[0];
62+
const pagesRouter = useRouter();
63+
const pathname = usePathname()!;
64+
const cleanedPath = pagesRouter
65+
? pagesRouter.asPath.split(/[\?\#]/)[0]
66+
: pathname;
67+
5868
const {route, nextRoute, prevRoute, breadcrumbs, order} = getRouteMeta(
5969
cleanedPath,
6070
routeTree
@@ -125,13 +135,15 @@ export function Page({
125135

126136
return (
127137
<>
128-
<Seo
129-
title={title}
130-
titleForTitleTag={meta.titleForTitleTag}
131-
isHomePage={isHomePage}
132-
image={`/images/og-` + section + '.png'}
133-
searchOrder={searchOrder}
134-
/>
138+
{!appRouter && (
139+
<Seo
140+
title={title}
141+
titleForTitleTag={meta.titleForTitleTag}
142+
isHomePage={isHomePage}
143+
image={`/images/og-` + section + '.png'}
144+
searchOrder={searchOrder}
145+
/>
146+
)}
135147
{(isHomePage || isBlogIndex) && (
136148
<Head>
137149
<link
@@ -169,7 +181,7 @@ export function Page({
169181
<main className="min-w-0 isolate">
170182
<article
171183
className="font-normal break-words text-primary dark:text-primary-dark"
172-
key={asPath}>
184+
key={cleanedPath}>
173185
{content}
174186
</article>
175187
<div
@@ -193,7 +205,9 @@ export function Page({
193205
</main>
194206
</Suspense>
195207
<div className="hidden -mt-16 lg:max-w-custom-xs 2xl:block">
196-
{showToc && toc.length > 0 && <Toc headings={toc} key={asPath} />}
208+
{showToc && toc.length > 0 && (
209+
<Toc headings={toc} key={cleanedPath} />
210+
)}
197211
</div>
198212
</div>
199213
</>

src/components/Layout/Sidebar/SidebarRouteTree.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
import {useRef, useLayoutEffect, Fragment} from 'react';
1313

1414
import cn from 'classnames';
15-
import {useRouter} from 'next/router';
1615
import {SidebarLink} from './SidebarLink';
1716
import {useCollapse} from 'react-collapsed';
1817
import usePendingRoute from 'hooks/usePendingRoute';
1918
import type {RouteItem} from 'components/Layout/getRouteMeta';
2019
import {siteConfig} from 'siteConfig';
20+
import {usePathname} from 'next/navigation';
2121

2222
interface SidebarRouteTreeProps {
2323
isForceExpanded: boolean;
@@ -84,7 +84,7 @@ export function SidebarRouteTree({
8484
routeTree,
8585
level = 0,
8686
}: SidebarRouteTreeProps) {
87-
const slug = useRouter().asPath.split(/[\?\#]/)[0];
87+
const slug = usePathname();
8888
const pendingRoute = usePendingRoute();
8989
const currentRoutes = routeTree.routes as RouteItem[];
9090
return (

src/components/MDX/ExpandableExample.tsx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use client';
2+
13
/**
24
* Copyright (c) Meta Platforms, Inc. and affiliates.
35
*
@@ -16,8 +18,20 @@ import {IconDeepDive} from '../Icon/IconDeepDive';
1618
import {IconCodeBlock} from '../Icon/IconCodeBlock';
1719
import {Button} from '../Button';
1820
import {H4} from './Heading';
19-
import {useRouter} from 'next/router';
20-
import {useEffect, useRef, useState} from 'react';
21+
import {useEffect, useRef, useState, useSyncExternalStore} from 'react';
22+
23+
function useHash() {
24+
return useSyncExternalStore(
25+
(callback) => {
26+
window.addEventListener('hashchange', callback);
27+
return () => {
28+
window.removeEventListener('hashchange', callback);
29+
};
30+
},
31+
() => window.location.hash,
32+
() => null
33+
);
34+
}
2135

2236
interface ExpandableExampleProps {
2337
children: React.ReactNode;
@@ -35,8 +49,8 @@ function ExpandableExample({children, excerpt, type}: ExpandableExampleProps) {
3549
const isExample = type === 'Example';
3650
const id = children[0].props.id;
3751

38-
const {asPath} = useRouter();
39-
const shouldAutoExpand = id === asPath.split('#')[1];
52+
const hash = useHash();
53+
const shouldAutoExpand = !!hash && id === hash.split('#')[1];
4054
const queuedExpandRef = useRef<boolean>(shouldAutoExpand);
4155
const [isExpanded, setIsExpanded] = useState(false);
4256

0 commit comments

Comments
 (0)