diff --git a/.changeset/icy-planets-know.md b/.changeset/icy-planets-know.md
new file mode 100644
index 000000000..d32303d87
--- /dev/null
+++ b/.changeset/icy-planets-know.md
@@ -0,0 +1,5 @@
+---
+'eslint-plugin-svelte': minor
+---
+
+feat(no-navigation-without-resolve): checking link shorthand attributes
diff --git a/packages/eslint-plugin-svelte/src/rules/no-navigation-without-resolve.ts b/packages/eslint-plugin-svelte/src/rules/no-navigation-without-resolve.ts
index 0beb2aa71..bd1e49f61 100644
--- a/packages/eslint-plugin-svelte/src/rules/no-navigation-without-resolve.ts
+++ b/packages/eslint-plugin-svelte/src/rules/no-navigation-without-resolve.ts
@@ -84,6 +84,26 @@ export default createRule('no-navigation-without-resolve', {
}
}
},
+ SvelteShorthandAttribute(node) {
+ if (
+ context.options[0]?.ignoreLinks === true ||
+ node.parent.parent.type !== 'SvelteElement' ||
+ node.parent.parent.kind !== 'html' ||
+ node.parent.parent.name.type !== 'SvelteName' ||
+ node.parent.parent.name.name !== 'a' ||
+ node.key.name !== 'href' ||
+ node.value.type !== 'Identifier'
+ ) {
+ return;
+ }
+ if (
+ !expressionIsAbsolute(new FindVariableContext(context), node.value) &&
+ !expressionIsFragment(new FindVariableContext(context), node.value) &&
+ !isResolveCall(new FindVariableContext(context), node.value, resolveReferences)
+ ) {
+ context.report({ loc: node.loc, messageId: 'linkWithoutResolve' });
+ }
+ },
SvelteAttribute(node) {
if (
context.options[0]?.ignoreLinks === true ||
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-partial-resolve01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-partial-resolve01-errors.yaml
index c9996ac7f..2049a0dbf 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-partial-resolve01-errors.yaml
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-partial-resolve01-errors.yaml
@@ -1,12 +1,16 @@
- message: Found a link with a url that isn't resolved.
- line: 7
+ line: 8
column: 9
suggestions: null
- message: Found a link with a url that isn't resolved.
- line: 8
+ line: 9
column: 9
suggestions: null
- message: Found a link with a url that isn't resolved.
- line: 9
+ line: 10
column: 9
suggestions: null
+- message: Found a link with a url that isn't resolved.
+ line: 11
+ column: 4
+ suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-partial-resolve01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-partial-resolve01-input.svelte
index 6994a2cb1..661e8c14e 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-partial-resolve01-input.svelte
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-partial-resolve01-input.svelte
@@ -2,8 +2,10 @@
import { resolve } from '$app/paths';
const value = resolve('/foo') + '/bar';
+ const href = resolve('/foo') + '/bar';
Click me!
Click me!
Click me!
+Click me!
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-with-fragment01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-with-fragment01-errors.yaml
index f6888e8c1..f5adbd301 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-with-fragment01-errors.yaml
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-with-fragment01-errors.yaml
@@ -1,10 +1,6 @@
-- message: Found a link with a url that isn't resolved.
- line: 5
- column: 10
- suggestions: null
- message: Found a link with a url that isn't resolved.
line: 6
- column: 9
+ column: 10
suggestions: null
- message: Found a link with a url that isn't resolved.
line: 7
@@ -18,3 +14,11 @@
line: 9
column: 9
suggestions: null
+- message: Found a link with a url that isn't resolved.
+ line: 10
+ column: 4
+ suggestions: null
+- message: Found a link with a url that isn't resolved.
+ line: 11
+ column: 9
+ suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-with-fragment01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-with-fragment01-input.svelte
index 2a2d1d418..8e955d59a 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-with-fragment01-input.svelte
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-with-fragment01-input.svelte
@@ -1,9 +1,11 @@
Click me!
Click me!
Click me!
Click me!
+Click me!
Click me!
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-without-resolve01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-without-resolve01-errors.yaml
index f6888e8c1..f5adbd301 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-without-resolve01-errors.yaml
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-without-resolve01-errors.yaml
@@ -1,10 +1,6 @@
-- message: Found a link with a url that isn't resolved.
- line: 5
- column: 10
- suggestions: null
- message: Found a link with a url that isn't resolved.
line: 6
- column: 9
+ column: 10
suggestions: null
- message: Found a link with a url that isn't resolved.
line: 7
@@ -18,3 +14,11 @@
line: 9
column: 9
suggestions: null
+- message: Found a link with a url that isn't resolved.
+ line: 10
+ column: 4
+ suggestions: null
+- message: Found a link with a url that isn't resolved.
+ line: 11
+ column: 9
+ suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-without-resolve01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-without-resolve01-input.svelte
index 4ae6bc7ec..2dab745ff 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-without-resolve01-input.svelte
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-without-resolve01-input.svelte
@@ -1,9 +1,11 @@
Click me!
Click me!
Click me!
Click me!
+Click me!
Click me!
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-absolute-url01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-absolute-url01-input.svelte
index 4b57ff9ba..cbc35c4a0 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-absolute-url01-input.svelte
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-absolute-url01-input.svelte
@@ -2,6 +2,7 @@
const protocol = 'https';
const value = "https://svelte.dev";
+ const href = "https://svelte.dev";
Click me!
@@ -16,3 +17,4 @@
Click me!
Click me!
Click me!
+Click me!
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-fragment-url01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-fragment-url01-input.svelte
index cf56203a5..2e35b7630 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-fragment-url01-input.svelte
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-fragment-url01-input.svelte
@@ -2,6 +2,7 @@
const section = 'sectionName';
const value = '#section';
+ const href = '#section';
Click me!
@@ -12,3 +13,4 @@
Click me!
Click me!
Click me!
+Click me!
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-resolved01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-resolved01-input.svelte
index 2561d7490..0ea7fca3a 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-resolved01-input.svelte
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-resolved01-input.svelte
@@ -2,7 +2,9 @@
import { resolve } from '$app/paths';
const value = resolve('/foo/');
+ const href = resolve('/foo/');
Click me!
Click me!
+Click me!