Skip to content

Commit

Permalink
docs(no-navigation-without-base): documented the new rule
Browse files Browse the repository at this point in the history
  • Loading branch information
marekdedic committed Nov 29, 2024
1 parent 556b8c0 commit 900cc96
Showing 1 changed file with 45 additions and 11 deletions.
56 changes: 45 additions & 11 deletions docs/rules/no-navigation-without-base.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ since: 'v2.36.0-next.9'
## :book: Rule Details

This rule reports navigation using SvelteKit's `goto()` function without prefixing a relative URL with the base path. If a non-prefixed relative URL is used for navigation, the `goto` function navigates away from the base path, which is usually not what you wanted to do (for external URLs, `window.location = url` should be used instead).
This rule reports navigation using HTML `<a>` tags, SvelteKit's `goto()`, `pushState()` and `replaceState()` functions without prefixing a relative URL with the base path. All four of these may be used for navigation, with `goto()`, `pushState()` and `replaceState()` being intended solely for iternal navigation (i.e. not leaving the site), while `<a>` tags may be used for both internal and external navigation. When using any way of internal navigation, the base path must be prepended, otherwise the site may break. For programmatic navigation to external URLs, using `window.location` is advised.

This rule checks all 4 navigation options for the presence of the base path, with an exception for `<a>` links to absolute URLs, which are assumed to be used for external navigation and so do not require the base path, and for shallow outing functions with an empty string as the path, which keeps the current URL.

<ESLintCodeBlock>

Expand All @@ -22,37 +24,69 @@ This rule reports navigation using SvelteKit's `goto()` function without prefixi
<script>
/* eslint svelte/no-navigation-without-base: "error" */
import { goto } from '$app/navigation';
import { goto, pushState, replaceState } from '$app/navigation';
import { base } from '$app/paths';
import { base as baseAlias } from '$app/paths';
// ✓ GOOD
goto(base + '/foo/');
goto(`${base}/foo/`);
goto(baseAlias + '/foo/');
goto(`${baseAlias}/foo/`);
pushState(base + '/foo/', {});
pushState(`${base}/foo/`, {});
pushState('', {});
goto('https://localhost/foo/');
replaceState(base + '/foo/', {});
replaceState(`${base}/foo/`, {});
replaceState('', {});
// ✗ BAD
goto('/foo');
goto('/foo/' + base);
goto(`/foo/${base}`);
pushState('/foo', {});
replaceState('/foo', {});
</script>
<!-- ✓ GOOD -->
<a href={base + '/foo/'}>Click me!</a>
<a href={`${base}/foo/`}>Click me!</a>
<a href="https://svelte.dev">Click me!</a>
<!-- ✗ BAD -->
<a href="/foo">Click me!</a>
<a href={'/foo'}>Click me!</a>
```

</ESLintCodeBlock>

## :wrench: Options

Nothing.
```json
{
"svelte/no-navigation-without-base": [
"error",
{
"ignoreGoto": false,
"ignoreLinks": false,
"ignorePushState": false,
"ignoreReplaceState": false
}
]
}
```

- `ignoreGoto` ... Whether to ignore all `goto()` calls. Default `false`.
- `ignoreLinks` ... Whether to ignore all `<a>` tags. Default `false`.
- `ignorePushState` ... Whether to ignore all `pushState()` calls. Default `false`.
- `ignoreReplaceState` ... Whether to ignore all `replaceState()` calls. Default `false`.

## :books: Further Reading

- [`goto()` documentation](https://kit.svelte.dev/docs/modules#$app-navigation-goto)
- [`base` documentation](https://kit.svelte.dev/docs/modules#$app-paths-base)
- [`base` documentation](https://svelte.dev/docs/kit/$app-paths#base)
- [Shallow routing](https://svelte.dev/docs/kit/shallow-routing)
- [`goto()` documentation](https://svelte.dev/docs/kit/$app-navigation#goto)
- [`pushState()` documentation](https://svelte.dev/docs/kit/$app-navigation#pushState)
- [`replaceState()` documentation](https://svelte.dev/docs/kit/$app-navigation#replaceState)

## :rocket: Version

Expand Down

0 comments on commit 900cc96

Please sign in to comment.