diff --git a/docs/src/content/docs/configuration.md b/docs/src/content/docs/configuration.md
index 9b10fae..f97b527 100644
--- a/docs/src/content/docs/configuration.md
+++ b/docs/src/content/docs/configuration.md
@@ -101,6 +101,30 @@ export default defineConfig({
})
```
+### `errorOnInvalidHashes`
+
+**Type:** `boolean`
+**Default:** `true`
+
+By default, the Starlight Links Validator plugin will error if an internal link points to an [hash](https://developer.mozilla.org/en-US/docs/Web/API/URL/hash) that does not exist in the target page.
+If you want to only validate that pages exist but ignore hashes, you can set this option to `false`.
+
+This option should be used with caution but can be useful in large documentation with many contributors where hashes always being up-to-date can be difficult to maintain and validated on a different schedule, e.g. once a week.
+
+```js {6}
+export default defineConfig({
+ integrations: [
+ starlight({
+ plugins: [
+ starlightLinksValidator({
+ errorOnInvalidHashes: false,
+ }),
+ ],
+ }),
+ ],
+})
+```
+
### `exclude`
**Type:** `string[]`
diff --git a/docs/src/content/docs/getting-started.mdx b/docs/src/content/docs/getting-started.mdx
index 88071d4..37b90c6 100644
--- a/docs/src/content/docs/getting-started.mdx
+++ b/docs/src/content/docs/getting-started.mdx
@@ -5,8 +5,8 @@ title: Getting Started
A [Starlight](https://starlight.astro.build) plugin to validate **_internal_** links in Markdown and MDX files.
- Validate internal links to other pages
-- Validate internal links to anchors in other pages
-- Validate internal links to anchors in the same page
+- Validate internal links to hashes in other pages
+- Validate internal links to hashes in the same page
- Ignore external links
- Run only during a production build
diff --git a/packages/starlight-links-validator/README.md b/packages/starlight-links-validator/README.md
index f61dd63..db11b44 100644
--- a/packages/starlight-links-validator/README.md
+++ b/packages/starlight-links-validator/README.md
@@ -27,8 +27,8 @@ Want to get started immediately? Check out the [getting started guide](https://s
A [Starlight](https://starlight.astro.build) plugin to validate **_internal_** links in Markdown and MDX files.
- Validate internal links to other pages
-- Validate internal links to anchors in other pages
-- Validate internal links to anchors in the same page
+- Validate internal links to hashes in other pages
+- Validate internal links to hashes in the same page
- Ignore external links
- Run only during a production build
diff --git a/packages/starlight-links-validator/index.ts b/packages/starlight-links-validator/index.ts
index 2c9480f..0298fa1 100644
--- a/packages/starlight-links-validator/index.ts
+++ b/packages/starlight-links-validator/index.ts
@@ -33,6 +33,14 @@ const starlightLinksValidatorOptionsSchema = z
* @default true
*/
errorOnRelativeLinks: z.boolean().default(true),
+ /**
+ * Defines whether the plugin should error on invalid hashes.
+ *
+ * When set to `false`, the plugin will only validate link pages and ignore hashes.
+ *
+ * @default true
+ */
+ errorOnInvalidHashes: z.boolean().default(true),
/**
* Defines a list of links or glob patterns that should be excluded from validation.
*
diff --git a/packages/starlight-links-validator/libs/validation.ts b/packages/starlight-links-validator/libs/validation.ts
index a1754ab..cbc08bf 100644
--- a/packages/starlight-links-validator/libs/validation.ts
+++ b/packages/starlight-links-validator/libs/validation.ts
@@ -15,7 +15,7 @@ import { getValidationData, type Headings } from './remark'
export const ValidationErrorType = {
InconsistentLocale: 'inconsistent locale',
- InvalidAnchor: 'invalid anchor',
+ InvalidHash: 'invalid hash',
InvalidLink: 'invalid link',
RelativeLink: 'relative link',
TrailingSlash: 'trailing slash',
@@ -59,7 +59,9 @@ export function validateLinks(
}
if (link.startsWith('#')) {
- validateSelfAnchor(validationContext)
+ if (options.errorOnInvalidHashes) {
+ validateSelfHash(validationContext)
+ }
} else {
validateLink(validationContext)
}
@@ -151,7 +153,9 @@ function validateLink(context: ValidationContext) {
}
if (hash && !fileHeadings.includes(hash)) {
- addError(errors, filePath, link, ValidationErrorType.InvalidAnchor)
+ if (options.errorOnInvalidHashes) {
+ addError(errors, filePath, link, ValidationErrorType.InvalidHash)
+ }
return
}
@@ -176,9 +180,9 @@ function getFileHeadings(path: string, { headings, localeConfig, options }: Vali
}
/**
- * Validate a link to an anchor in the same page.
+ * Validate a link to an hash in the same page.
*/
-function validateSelfAnchor({ errors, link, filePath, headings }: ValidationContext) {
+function validateSelfHash({ errors, link, filePath, headings }: ValidationContext) {
const sanitizedHash = link.replace(/^#/, '')
const fileHeadings = headings.get(filePath)
@@ -187,7 +191,7 @@ function validateSelfAnchor({ errors, link, filePath, headings }: ValidationCont
}
if (!fileHeadings.includes(sanitizedHash)) {
- addError(errors, filePath, link, 'invalid anchor')
+ addError(errors, filePath, link, ValidationErrorType.InvalidHash)
}
}
diff --git a/packages/starlight-links-validator/tests/base-path.test.ts b/packages/starlight-links-validator/tests/base-path.test.ts
index d37059d..b766117 100644
--- a/packages/starlight-links-validator/tests/base-path.test.ts
+++ b/packages/starlight-links-validator/tests/base-path.test.ts
@@ -19,8 +19,8 @@ test('should validate links when the `base` Astro option is set', async () => {
['/guides/example/#description', ValidationErrorType.InvalidLink],
['/unknown', ValidationErrorType.InvalidLink],
['/unknown/', ValidationErrorType.InvalidLink],
- ['/test/guides/example#unknown', ValidationErrorType.InvalidAnchor],
- ['/test/guides/example/#unknown', ValidationErrorType.InvalidAnchor],
+ ['/test/guides/example#unknown', ValidationErrorType.InvalidHash],
+ ['/test/guides/example/#unknown', ValidationErrorType.InvalidHash],
['/favicon.svg', ValidationErrorType.InvalidLink],
['/guidelines/dummy.pdf', ValidationErrorType.InvalidLink],
])
diff --git a/packages/starlight-links-validator/tests/basics.test.ts b/packages/starlight-links-validator/tests/basics.test.ts
index 177c2ff..6c8cbba 100644
--- a/packages/starlight-links-validator/tests/basics.test.ts
+++ b/packages/starlight-links-validator/tests/basics.test.ts
@@ -27,35 +27,35 @@ test('should not build with invalid links', async () => {
['/unknown/', ValidationErrorType.InvalidLink],
['/unknown#title', ValidationErrorType.InvalidLink],
['/unknown/#title', ValidationErrorType.InvalidLink],
- ['#links', ValidationErrorType.InvalidAnchor],
- ['/guides/example/#links', ValidationErrorType.InvalidAnchor],
+ ['#links', ValidationErrorType.InvalidHash],
+ ['/guides/example/#links', ValidationErrorType.InvalidHash],
['/icon.svg', ValidationErrorType.InvalidLink],
['/guidelines/ui.pdf', ValidationErrorType.InvalidLink],
['/unknown-ref', ValidationErrorType.InvalidLink],
- ['#unknown-ref', ValidationErrorType.InvalidAnchor],
- ['#anotherDiv', ValidationErrorType.InvalidAnchor],
+ ['#unknown-ref', ValidationErrorType.InvalidHash],
+ ['#anotherDiv', ValidationErrorType.InvalidHash],
['/guides/page-with-custom-slug', ValidationErrorType.InvalidLink],
['/release/@pkg/v0.2.0', ValidationErrorType.InvalidLink],
])
expectValidationErrors(error, 'guides/example/', [
- ['#links', ValidationErrorType.InvalidAnchor],
+ ['#links', ValidationErrorType.InvalidHash],
['/unknown/#links', ValidationErrorType.InvalidLink],
['/unknown', ValidationErrorType.InvalidLink],
- ['#anotherBlock', ValidationErrorType.InvalidAnchor],
+ ['#anotherBlock', ValidationErrorType.InvalidHash],
['/icon.svg', ValidationErrorType.InvalidLink],
['/guidelines/ui.pdf', ValidationErrorType.InvalidLink],
['/linkcard/', ValidationErrorType.InvalidLink],
['/linkcard/#links', ValidationErrorType.InvalidLink],
- ['#linkcard', ValidationErrorType.InvalidAnchor],
+ ['#linkcard', ValidationErrorType.InvalidHash],
['/linkbutton/', ValidationErrorType.InvalidLink],
['/linkbutton/#links', ValidationErrorType.InvalidLink],
- ['#linkbutton', ValidationErrorType.InvalidAnchor],
+ ['#linkbutton', ValidationErrorType.InvalidHash],
])
expectValidationErrors(error, 'guides/namespacetest/', [
- ['#some-other-content', ValidationErrorType.InvalidAnchor],
- ['/guides/namespacetest/#another-content', ValidationErrorType.InvalidAnchor],
+ ['#some-other-content', ValidationErrorType.InvalidHash],
+ ['/guides/namespacetest/#another-content', ValidationErrorType.InvalidHash],
])
expectValidationErrors(error, 'relative/', [
diff --git a/packages/starlight-links-validator/tests/custom-ids.test.ts b/packages/starlight-links-validator/tests/custom-ids.test.ts
index 9fb6f74..7578879 100644
--- a/packages/starlight-links-validator/tests/custom-ids.test.ts
+++ b/packages/starlight-links-validator/tests/custom-ids.test.ts
@@ -12,6 +12,6 @@ test('should validate links with custom IDs', async () => {
} catch (error) {
expectValidationErrorCount(error, 1, 1)
- expectValidationErrors(error, 'test/', [['#heading-with-custom-id', ValidationErrorType.InvalidAnchor]])
+ expectValidationErrors(error, 'test/', [['#heading-with-custom-id', ValidationErrorType.InvalidHash]])
}
})
diff --git a/packages/starlight-links-validator/tests/fallback.test.ts b/packages/starlight-links-validator/tests/fallback.test.ts
index 0f5b90d..686ffdb 100644
--- a/packages/starlight-links-validator/tests/fallback.test.ts
+++ b/packages/starlight-links-validator/tests/fallback.test.ts
@@ -36,8 +36,8 @@ test('should not build with invalid fallback links', async () => {
expectValidationErrors(error, 'en/', [
['/en/guides/unknown', ValidationErrorType.InvalidLink],
['/en/guides/unknown/', ValidationErrorType.InvalidLink],
- ['/en/guides/example#unknown', ValidationErrorType.InvalidAnchor],
- ['/en/guides/example/#unknown', ValidationErrorType.InvalidAnchor],
+ ['/en/guides/example#unknown', ValidationErrorType.InvalidHash],
+ ['/en/guides/example/#unknown', ValidationErrorType.InvalidHash],
['/es/guides/example', ValidationErrorType.InvalidLink],
['/es/guides/example/', ValidationErrorType.InvalidLink],
])
@@ -45,8 +45,8 @@ test('should not build with invalid fallback links', async () => {
expectValidationErrors(error, 'fr/', [
['/fr/guides/unknown', ValidationErrorType.InvalidLink],
['/fr/guides/unknown/', ValidationErrorType.InvalidLink],
- ['/fr/guides/example#unknown', ValidationErrorType.InvalidAnchor],
- ['/fr/guides/example/#unknown', ValidationErrorType.InvalidAnchor],
+ ['/fr/guides/example#unknown', ValidationErrorType.InvalidHash],
+ ['/fr/guides/example/#unknown', ValidationErrorType.InvalidHash],
])
expectValidationErrors(error, 'fr/guides/test/', [['/', ValidationErrorType.InvalidLink]])
@@ -68,8 +68,8 @@ test('should not build with a root locale and invalid fallback links', async ()
expectValidationErrors(error, '/', [
['/guides/unknown', ValidationErrorType.InvalidLink],
['/guides/unknown/', ValidationErrorType.InvalidLink],
- ['/guides/example#unknown', ValidationErrorType.InvalidAnchor],
- ['/guides/example/#unknown', ValidationErrorType.InvalidAnchor],
+ ['/guides/example#unknown', ValidationErrorType.InvalidHash],
+ ['/guides/example/#unknown', ValidationErrorType.InvalidHash],
['/es/guides/example', ValidationErrorType.InvalidLink],
['/es/guides/example/', ValidationErrorType.InvalidLink],
])
@@ -77,8 +77,8 @@ test('should not build with a root locale and invalid fallback links', async ()
expectValidationErrors(error, 'fr/', [
['/fr/guides/unknown', ValidationErrorType.InvalidLink],
['/fr/guides/unknown/', ValidationErrorType.InvalidLink],
- ['/fr/guides/example#unknown', ValidationErrorType.InvalidAnchor],
- ['/fr/guides/example/#unknown', ValidationErrorType.InvalidAnchor],
+ ['/fr/guides/example#unknown', ValidationErrorType.InvalidHash],
+ ['/fr/guides/example/#unknown', ValidationErrorType.InvalidHash],
])
expectValidationErrors(error, 'guides/test/', [['/en', ValidationErrorType.InvalidLink]])
diff --git a/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/guides/example.mdx b/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/guides/example.mdx
index 5cff26e..972f2b1 100644
--- a/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/guides/example.mdx
+++ b/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/guides/example.mdx
@@ -13,8 +13,8 @@ import { Card, CardGrid, LinkCard, LinkButton } from '@astrojs/starlight/compone
## Some links
-- [Link to invalid anchor in the same page](#links)
-- [Link to invalid anchor in another page](/unknown/#links)
+- [Link to invalid hash in the same page](#links)
+- [Link to invalid hash in another page](/unknown/#links)
HTML link to unknown page
@@ -37,10 +37,10 @@ some content
-
-
+
+
LinkButton: unknown page
-LinkButton: unknown page and anchor
-LinkButton: unknown anchor
+LinkButton: unknown page and hash
+LinkButton: unknown hash
diff --git a/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/test.md b/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/test.md
index 6c63e25..5150ea5 100644
--- a/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/test.md
+++ b/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/test.md
@@ -18,20 +18,20 @@ title: Test
# More links
-- [Link to valid anchor in this page](#some-links)
-- [Link to invalid anchor in this page](#links)
-- [Link to valid anchor in another MDX page](/guides/example/#some-links)
-- [Link to invalid anchor in another MDX page](/guides/example/#links)
+- [Link to valid hash in this page](#some-links)
+- [Link to invalid hash in this page](#links)
+- [Link to valid hash in another MDX page](/guides/example/#some-links)
+- [Link to invalid hash in another MDX page](/guides/example/#links)
- [Link to invalid asset](/icon.svg)
- [Link to another invalid asset](/guidelines/ui.pdf)
## Links with references
- [Link reference to unknwon page][ref-unknown-page]
-- [Link reference to invalid anchor][ref-invalid-anchor]
+- [Link reference to invalid hash][ref-invalid-hash]
[ref-unknown-page]: /unknown-ref
-[ref-invalid-anchor]: #unknown-ref
+[ref-invalid-hash]: #unknown-ref
some content
diff --git a/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/guides/example.mdx b/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/guides/example.mdx
index 861927c..9e670f9 100644
--- a/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/guides/example.mdx
+++ b/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/guides/example.mdx
@@ -13,7 +13,7 @@ import { Card, CardGrid, LinkCard, LinkButton } from '@astrojs/starlight/compone
## Some links
-- [Link to anchor in the same page](#some-links)
+- [Link to hash in the same page](#some-links)
HTML link to another page
@@ -40,10 +40,10 @@ some content
-
-
+
+
LinkCard: unknown page
-
LinkCard: unknown page and anchor
-
LinkCard: unknown anchor
+
LinkCard: unknown page and hash
+
LinkCard: unknown hash
diff --git a/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/index.md b/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/index.md
index 96cc519..06af854 100644
--- a/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/index.md
+++ b/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/index.md
@@ -21,25 +21,25 @@ title: Index
# More links
-- [Link to anchor in this page](#some-links)
-- [Link to anchor in another MDX page](/guides/example/#some-links)
+- [Link to hash in this page](#some-links)
+- [Link to hash in another MDX page](/guides/example/#some-links)
- [Link to an asset](/favicon.svg)
- [Link to another asset](/guidelines/dummy.pdf)
## A more `complex` heading
-- [Link to more complex anchor](#a-more-complex-heading)
+- [Link to more complex hash](#a-more-complex-heading)
## Links with references
- [ref]
- [Link reference][ref]
-- [Link reference with anchor in this page][ref-with-anchor-internal]
-- [Link reference with anchor in another page][ref-with-anchor-external]
+- [Link reference with hash in this page][ref-with-hash-internal]
+- [Link reference with hash in another page][ref-with-hash-external]
[ref]: /test
-[ref-with-anchor-internal]: #some-links
-[ref-with-anchor-external]: /test#title
+[ref-with-hash-internal]: #some-links
+[ref-with-hash-external]: /test#title
## Link to page with custom slug
diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/astro.config.ts b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/astro.config.ts
new file mode 100644
index 0000000..3ffc24f
--- /dev/null
+++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/astro.config.ts
@@ -0,0 +1,13 @@
+import starlight from '@astrojs/starlight'
+import { defineConfig } from 'astro/config'
+
+import starlightLinksValidator from '../..'
+
+export default defineConfig({
+ integrations: [
+ starlight({
+ plugins: [starlightLinksValidator({ errorOnInvalidHashes: false })],
+ title: 'Starlight Links Validator Tests - invalid hashes invalid links',
+ }),
+ ],
+})
diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/guides/example.mdx b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/guides/example.mdx
new file mode 100644
index 0000000..972f2b1
--- /dev/null
+++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/guides/example.mdx
@@ -0,0 +1,46 @@
+---
+title: Example
+---
+
+import { Card, CardGrid, LinkCard, LinkButton } from '@astrojs/starlight/components'
+
+## Steps
+
+
+ Do something
+ Do something else
+
+
+## Some links
+
+- [Link to invalid hash in the same page](#links)
+- [Link to invalid hash in another page](/unknown/#links)
+
+
HTML link to unknown page
+
+
+some content
+
+some content
+
+some content
+
+some content
+
+
+ test
+
+
+
+
Link to invalid asset
+
Link to another invalid asset
+
+
+
+
+
+
+
+
LinkButton: unknown page
+
LinkButton: unknown page and hash
+
LinkButton: unknown hash
diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/test.md b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/test.md
new file mode 100644
index 0000000..c01041e
--- /dev/null
+++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/test.md
@@ -0,0 +1,48 @@
+---
+title: Test
+---
+
+# Some links
+
+- [External link](https://starlight.astro.build/)
+
+- [External link prefixed with a slash](/https://starlight.astro.build/)
+
+- [Home page](/)
+
+- [Unknown page](/unknown)
+- [Unknown page](/unknown/)
+
+- [Unknown page with hash](/unknown#title)
+- [Unknown page with hash](/unknown/#title)
+
+# More links
+
+- [Link to valid hash in this page](#some-links)
+- [Link to invalid hash in this page](#links)
+- [Link to valid hash in another MDX page](/guides/example/#some-links)
+- [Link to invalid hash in another MDX page](/guides/example/#links)
+- [Link to invalid asset](/icon.svg)
+- [Link to another invalid asset](/guidelines/ui.pdf)
+
+## Links with references
+
+- [Link reference to unknown page][ref-unknown-page]
+- [Link reference to invalid hash][ref-invalid-hash]
+
+[ref-unknown-page]: /unknown-ref
+[ref-invalid-hash]: #unknown-ref
+
+
+some content
+
+some content
+
+some content
+
+some content
+
+
+ test
+
+
diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/astro.config.ts b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/astro.config.ts
new file mode 100644
index 0000000..3b15f9f
--- /dev/null
+++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/astro.config.ts
@@ -0,0 +1,13 @@
+import starlight from '@astrojs/starlight'
+import { defineConfig } from 'astro/config'
+
+import starlightLinksValidator from '../..'
+
+export default defineConfig({
+ integrations: [
+ starlight({
+ plugins: [starlightLinksValidator({ errorOnInvalidHashes: false })],
+ title: 'Starlight Links Validator Tests - invalid hashes valid links',
+ }),
+ ],
+})
diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/guides/example.mdx b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/guides/example.mdx
new file mode 100644
index 0000000..3dcc264
--- /dev/null
+++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/guides/example.mdx
@@ -0,0 +1,47 @@
+---
+title: Example
+---
+
+import { Card, CardGrid, LinkCard, LinkButton } from '@astrojs/starlight/components'
+
+## Steps
+
+
+ Do something
+ Do something else
+
+
+## Some links
+
+- [Link to valid hash in the same page](#some-links)
+- [Link to invalid hash in the same page](#unknown)
+
+
+
+
+
+
+
+
+
+
+
LinkCard: unknown page and valid hash
+
LinkCard: unknown page and invalid hash
+
LinkCard: valid hash
+
LinkCard: invalid hash
diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/index.md b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/index.md
new file mode 100644
index 0000000..0ec4cd7
--- /dev/null
+++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/index.md
@@ -0,0 +1,38 @@
+---
+title: Index
+---
+
+# Some links
+
+- [External link](https://starlight.astro.build/)
+
+- [Home page](/)
+
+- [Test page](/test)
+- [Test page](/test/)
+
+- [Test page with valid hash](/test#title)
+- [Test page with valid hash](/test/#title)
+
+- [Test page with invalid hash](/test#unknown)
+- [Test page with invalid hash](/test/#unknown)
+
+# More links
+
+- [Link to valid hash in this page](#some-links)
+- [Link to invalid hash in this page](#unknown)
+- [Link to valid hash in another MDX page](/guides/example/#some-links)
+- [Link to invalid hash in another MDX page](/guides/example/#unknown)
+
+## Links with references
+
+- [Link reference with valid hash in this page][ref-with-valid-hash-internal]
+- [Link reference with valid hash in another page][ref-with-valid-hash-external]
+
+- [Link reference with invalid hash in this page][ref-with-invalid-hash-internal]
+- [Link reference with invalid hash in another page][ref-with-invalid-hash-external]
+
+[ref-with-valid-hash-internal]: #some-links
+[ref-with-valid-hash-external]: /test#title
+[ref-with-invalid-hash-internal]: #unknown
+[ref-with-invalid-hash-external]: /test#unknown
diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/test.md b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/test.md
new file mode 100644
index 0000000..1bba7cc
--- /dev/null
+++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/test.md
@@ -0,0 +1,27 @@
+---
+title: Test
+---
+
+## Title
+
+Some content.
+
+- [Link to same page](/test)
+
+
+some content
+
+some content
+
+some content
+
+some content
+
+
+ test
+
+
+
+## Title
+
+More content.
diff --git a/packages/starlight-links-validator/tests/invalid-hashes.test.ts b/packages/starlight-links-validator/tests/invalid-hashes.test.ts
new file mode 100644
index 0000000..8f5a11f
--- /dev/null
+++ b/packages/starlight-links-validator/tests/invalid-hashes.test.ts
@@ -0,0 +1,42 @@
+import { expect, test } from 'vitest'
+
+import { ValidationErrorType } from '../libs/validation'
+
+import { expectValidationErrorCount, expectValidationErrors, loadFixture } from './utils'
+
+test('should build with invalid hashes', async () => {
+ await expect(loadFixture('invalid-hashes-valid-links')).resolves.not.toThrow()
+})
+
+test('should not build with invalid links but ignore invalid hashes', async () => {
+ expect.assertions(3)
+
+ try {
+ await loadFixture('invalid-hashes-invalid-links')
+ } catch (error) {
+ expectValidationErrorCount(error, 17, 2)
+
+ expectValidationErrors(error, 'test/', [
+ ['/https://starlight.astro.build/', ValidationErrorType.InvalidLink],
+ ['/', ValidationErrorType.InvalidLink],
+ ['/unknown', ValidationErrorType.InvalidLink],
+ ['/unknown/', ValidationErrorType.InvalidLink],
+ ['/unknown#title', ValidationErrorType.InvalidLink],
+ ['/unknown/#title', ValidationErrorType.InvalidLink],
+ ['/icon.svg', ValidationErrorType.InvalidLink],
+ ['/guidelines/ui.pdf', ValidationErrorType.InvalidLink],
+ ['/unknown-ref', ValidationErrorType.InvalidLink],
+ ])
+
+ expectValidationErrors(error, 'guides/example/', [
+ ['/unknown/#links', ValidationErrorType.InvalidLink],
+ ['/unknown', ValidationErrorType.InvalidLink],
+ ['/icon.svg', ValidationErrorType.InvalidLink],
+ ['/guidelines/ui.pdf', ValidationErrorType.InvalidLink],
+ ['/linkcard/', ValidationErrorType.InvalidLink],
+ ['/linkcard/#links', ValidationErrorType.InvalidLink],
+ ['/linkbutton/', ValidationErrorType.InvalidLink],
+ ['/linkbutton/#links', ValidationErrorType.InvalidLink],
+ ])
+ }
+})
diff --git a/packages/starlight-links-validator/tests/relative.test.ts b/packages/starlight-links-validator/tests/relative.test.ts
index 871d381..6b7f173 100644
--- a/packages/starlight-links-validator/tests/relative.test.ts
+++ b/packages/starlight-links-validator/tests/relative.test.ts
@@ -15,8 +15,8 @@ test('should ignore relative links when the `errorOnRelativeLinks` option is set
expectValidationErrors(error, 'test/', [
['/unknown', ValidationErrorType.InvalidLink],
['/unknown/', ValidationErrorType.InvalidLink],
- ['/guides/example#unknown', ValidationErrorType.InvalidAnchor],
- ['/guides/example/#unknown', ValidationErrorType.InvalidAnchor],
+ ['/guides/example#unknown', ValidationErrorType.InvalidHash],
+ ['/guides/example/#unknown', ValidationErrorType.InvalidHash],
])
}
})
diff --git a/packages/starlight-links-validator/tests/src-dir.test.ts b/packages/starlight-links-validator/tests/src-dir.test.ts
index a00d240..a7fafcf 100644
--- a/packages/starlight-links-validator/tests/src-dir.test.ts
+++ b/packages/starlight-links-validator/tests/src-dir.test.ts
@@ -15,8 +15,8 @@ test('should validate links when the `srcDir` Astro option is set', async () =>
expectValidationErrors(error, 'test/', [
['/unknown', ValidationErrorType.InvalidLink],
['/unknown/', ValidationErrorType.InvalidLink],
- ['/guides/example#unknown', ValidationErrorType.InvalidAnchor],
- ['/guides/example/#unknown', ValidationErrorType.InvalidAnchor],
+ ['/guides/example#unknown', ValidationErrorType.InvalidHash],
+ ['/guides/example/#unknown', ValidationErrorType.InvalidHash],
])
}
})
diff --git a/packages/starlight-links-validator/tests/trailing.test.ts b/packages/starlight-links-validator/tests/trailing.test.ts
index 9c343c5..f3e4b90 100644
--- a/packages/starlight-links-validator/tests/trailing.test.ts
+++ b/packages/starlight-links-validator/tests/trailing.test.ts
@@ -17,8 +17,8 @@ test('should validate links when the `trailingSlash` Astro option is set to `nev
['/guides/example/#description', ValidationErrorType.TrailingSlash],
['/unknown', ValidationErrorType.InvalidLink],
['/unknown/', ValidationErrorType.InvalidLink],
- ['/guides/example#unknown', ValidationErrorType.InvalidAnchor],
- ['/guides/example/#unknown', ValidationErrorType.InvalidAnchor],
+ ['/guides/example#unknown', ValidationErrorType.InvalidHash],
+ ['/guides/example/#unknown', ValidationErrorType.InvalidHash],
])
}
})
@@ -36,8 +36,8 @@ test('should validate links when the `trailingSlash` Astro option is set to `alw
['/guides/example#description', ValidationErrorType.TrailingSlash],
['/unknown', ValidationErrorType.InvalidLink],
['/unknown/', ValidationErrorType.InvalidLink],
- ['/guides/example#unknown', ValidationErrorType.InvalidAnchor],
- ['/guides/example/#unknown', ValidationErrorType.InvalidAnchor],
+ ['/guides/example#unknown', ValidationErrorType.InvalidHash],
+ ['/guides/example/#unknown', ValidationErrorType.InvalidHash],
])
}
})