Skip to content

Commit

Permalink
Fix docs on NavLink w.r.t. links to the root route and the end prop (#…
Browse files Browse the repository at this point in the history
…10757)

* Fix docs on NavLink w.r.t. links to the root route and the end prop

* Update
  • Loading branch information
brophdawg11 committed Aug 2, 2023
1 parent a0d6c4f commit b23d7b5
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 16 deletions.
20 changes: 4 additions & 16 deletions docs/components/nav-link.md
Expand Up @@ -84,29 +84,17 @@ You can pass a render prop as children to customize the content of the `<NavLink

The `end` prop changes the matching logic for the `active` and `pending` states to only match to the "end" of the NavLink's `to` path. If the URL is longer than `to`, it will no longer be considered active.

Without the end prop, this link is always active because every URL matches `/`.

```tsx
<NavLink to="/">Home</NavLink>
```

To match the URL "to the end" of `to`, use `end`:

```tsx
<NavLink to="/" end>
Home
</NavLink>
```

Now this link will only be active at `"/"`. This works for paths with more segments as well:

| Link | URL | isActive |
| ----------------------------- | ------------ | -------- |
| `<NavLink to="/tasks" />` | `/tasks` | true |
| `<NavLink to="/tasks" />` | `/tasks/123` | true |
| `<NavLink to="/tasks" end />` | `/tasks` | true |
| `<NavLink to="/tasks" end />` | `/tasks/123` | false |

**A note on links to the root route**

`<NavLink to="/">` is an exceptional case because _every_ URL matches `/`. To avoid this matching every single route by default, it effectively ignores the `end` prop and only matches when you're at the root route.

## `caseSensitive`

Adding the `caseSensitive` prop changes the matching logic to make it case sensitive.
Expand Down
36 changes: 36 additions & 0 deletions packages/react-router-dom/__tests__/nav-link-active-test.tsx
Expand Up @@ -317,6 +317,42 @@ describe("NavLink", () => {
expect(anchors.map((a) => a.props.className)).toEqual(["active", ""]);
});

it("matches the root route with or without the end prop", () => {
let renderer: TestRenderer.ReactTestRenderer;
TestRenderer.act(() => {
renderer = TestRenderer.create(
<MemoryRouter>
<Routes>
<Route index element={<NavLink to="/">Root</NavLink>} />
</Routes>
</MemoryRouter>
);
});

let anchor = renderer.root.findByType("a");
expect(anchor.props.className).toMatch("active");

TestRenderer.act(() => {
renderer = TestRenderer.create(
<MemoryRouter>
<Routes>
<Route
index
element={
<NavLink to="/" end>
Root
</NavLink>
}
/>
</Routes>
</MemoryRouter>
);
});

anchor = renderer.root.findByType("a");
expect(anchor.props.className).toMatch("active");
});

it("does not automatically apply to root non-layout segments", () => {
let renderer: TestRenderer.ReactTestRenderer;
TestRenderer.act(() => {
Expand Down

0 comments on commit b23d7b5

Please sign in to comment.