From 47d2dfdb5472e14320fe7e824cc680b6f28b58bc Mon Sep 17 00:00:00 2001
From: Miroslav Petrov <46135319+petrovmiroslav@users.noreply.github.com>
Date: Mon, 26 Feb 2024 18:40:16 +0200
Subject: [PATCH] Update examples/active-class-name (#62506)
### Description
The current implementation of the activeClassName example doesn't
support the `UrlObject` type for the "href" Link prop.
For example
```
Dynamic Route
```
won't work.
### Suggestion
We can use the `resolveHref` function to handle all cases.
Co-authored-by: Sam Ko
---
.../components/ActiveLink.tsx | 44 ++++++++++++++-----
1 file changed, 32 insertions(+), 12 deletions(-)
diff --git a/examples/active-class-name/components/ActiveLink.tsx b/examples/active-class-name/components/ActiveLink.tsx
index 6bae8c9639..472ab98ea6 100644
--- a/examples/active-class-name/components/ActiveLink.tsx
+++ b/examples/active-class-name/components/ActiveLink.tsx
@@ -1,6 +1,26 @@
import { useRouter } from "next/router";
import Link, { LinkProps } from "next/link";
-import React, { PropsWithChildren, useState, useEffect } from "react";
+import React, { PropsWithChildren, useEffect, useState } from "react";
+import { NextRouter } from "next/src/shared/lib/router/router";
+import { resolveHref } from "next/dist/client/resolve-href";
+
+const getLinkUrl = (params: {
+ router: NextRouter;
+ href: LinkProps["href"];
+ as: LinkProps["as"];
+}): string => {
+ // Dynamic route will be matched via props.as
+ // Static route will be matched via props.href
+ if (params.as) return resolveHref(params.router, params.as);
+
+ const [resolvedHref, resolvedAs] = resolveHref(
+ params.router,
+ params.href,
+ true,
+ );
+
+ return resolvedAs || resolvedHref;
+};
type ActiveLinkProps = LinkProps & {
className?: string;
@@ -13,21 +33,22 @@ const ActiveLink = ({
className,
...props
}: PropsWithChildren) => {
- const { asPath, isReady } = useRouter();
+ const router = useRouter();
const [computedClassName, setComputedClassName] = useState(className);
useEffect(() => {
// Check if the router fields are updated client-side
- if (isReady) {
- // Dynamic route will be matched via props.as
- // Static route will be matched via props.href
- const linkPathname = new URL(
- (props.as || props.href) as string,
- location.href,
- ).pathname;
+ if (router.isReady) {
+ const linkUrl = getLinkUrl({
+ router,
+ href: props.href,
+ as: props.as,
+ });
+
+ const linkPathname = new URL(linkUrl, location.href).pathname;
// Using URL().pathname to get rid of query and hash
- const activePathname = new URL(asPath, location.href).pathname;
+ const activePathname = new URL(router.asPath, location.href).pathname;
const newClassName =
linkPathname === activePathname
@@ -39,8 +60,7 @@ const ActiveLink = ({
}
}
}, [
- asPath,
- isReady,
+ router,
props.as,
props.href,
activeClassName,