diff --git a/README.md b/README.md
index a156b514e..d31b0086a 100644
--- a/README.md
+++ b/README.md
@@ -144,7 +144,7 @@ export default function App() {
}
```
-The `` tag also has an `active` class if its href matches the current location, and `inactive` otherwise. **Note:** By default matching includes locations that are descendents (eg. href `/users` matches locations `/users` and `/users/123`), use the boolean `end` prop to prevent matching these. This is particularly useful for links to the root route `/` which would match everything.
+The `` tag also has an `active` class if its href matches the current location and `inactive` class otherwise. By providing the property `exactActiveClass`, you can opt in to a third state, which is `exactActive` and is set when the href matches the current location exactly. **Note:** By default matching includes locations that are descendents (eg. href `/users` matches locations `/users` and `/users/123`). If no `exactActiveClass` property was provided, `active` class will be set for both partially and exactly matching routes.
| prop | type | description |
@@ -154,8 +154,9 @@ The `` tag also has an `active` class if its href matches the current locatio
| replace | boolean | If true, don't add a new entry to the browser history. (By default, the new page will be added to the browser history, so pressing the back button will take you to the previous route.) |
| state | unknown | [Push this value](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) to the history stack when navigating | |
| inactiveClass | string | The class to show when the link is inactive (when the current location doesn't match the link) |
-| activeClass | string | The class to show when the link is active |
-| end | boolean | If `true`, only considers the link to be active when the curent location matches the `href` exactly; if `false`, check if the current location _starts with_ `href` |
+| activeClass | string | The class to show when the link is active, i.e. the current location _starts with_ `href` |
+| exactActiveClass | string or true | The class to show when the link matches the `href` exactly. If `true`, applies `exactActive` class and enables strict matching - i.e. `activeClass` will not apply for an exact match.
+| end | boolean | **Deprecated** If `true`, only considers the link to be active when the curent location matches the `href` exactly; if `false`, check if the current location _starts with_ `href` - providing `exactActiveClass` overrides this behavior | |
### The Navigate Component
Solid Router provides a `Navigate` component that works similarly to `A`, but it will _immediately_ navigate to the provided path as soon as the component is rendered. It also uses the `href` prop, but you have the additional option of passing a function to `href` that returns a path to navigate to:
diff --git a/src/components.tsx b/src/components.tsx
index 095339bce..08840f62c 100644
--- a/src/components.tsx
+++ b/src/components.tsx
@@ -208,6 +208,10 @@ export interface AnchorProps extends Omit props.href);
const href = useHref(to);
const location = useLocation();
- const isActive = createMemo(() => {
+ const matchedHref = createMemo(() => {
const to_ = to();
- if (to_ === undefined) return false;
+ if (to_ === undefined) return [false, false];
const path = normalizePath(to_.split(/[?#]/, 1)[0]).toLowerCase();
const loc = normalizePath(location.pathname).toLowerCase();
- return props.end ? path === loc : loc.startsWith(path);
+ return [loc.startsWith(path), path === loc];
});
+ const isLooseMatch = createMemo(() => matchedHref()[0])
+ const isExactMatch = createMemo(() => matchedHref()[1] && Boolean(props.exactActiveClass))
+
+ // Remove together with `end` property
+ // If end was provided return an exact match, else return loose match (as long as users don't opt in for new behavior)
+ const isActiveDeprecated = createMemo(() => props.end ? matchedHref()[1] : !props.exactActiveClass && isLooseMatch())
+
return (
);
}