Skip to content

Commit f9fdd45

Browse files
authored
Merge pull request #36 from objectstack-ai/copilot/validate-links-integration
2 parents 649db86 + dd439c7 commit f9fdd45

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"title": "Integrations",
3+
"pages": [
4+
"validate-links"
5+
]
6+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
---
2+
title: Validate Links
3+
description: Ensure your links are correct in documentation files.
4+
---
5+
6+
# Validate Links
7+
8+
Ensure your links are correct in your documentation.
9+
10+
## Setup
11+
12+
<Callout type="info">
13+
You can use [`next-validate-link`](https://next-validate-link.vercel.app) to validate your links in content files.
14+
</Callout>
15+
16+
<Callout type="warn">
17+
This guide is mainly for **Fumadocs MDX**, see the docs of `next-validate-link` for other setups.
18+
</Callout>
19+
20+
Create a script:
21+
22+
```ts title="scripts/lint.ts"
23+
import { type FileObject, printErrors, scanURLs, validateFiles } from 'next-validate-link';
24+
import type { InferPageType } from 'fumadocs-core/source';
25+
import { source } from '@/lib/source';
26+
27+
async function checkLinks() {
28+
const scanned = await scanURLs({
29+
// pick a preset for your React framework
30+
preset: 'next',
31+
populate: {
32+
'docs/[[...slug]]': source.getPages().map((page) => {
33+
return {
34+
value: {
35+
slug: page.slugs,
36+
},
37+
hashes: getHeadings(page),
38+
};
39+
}),
40+
},
41+
});
42+
43+
printErrors(
44+
await validateFiles(await getFiles(), {
45+
scanned,
46+
// check `href` attributes in different MDX components
47+
markdown: {
48+
components: {
49+
Card: { attributes: ['href'] },
50+
},
51+
},
52+
// check relative paths
53+
checkRelativePaths: 'as-url',
54+
}),
55+
true,
56+
);
57+
}
58+
59+
function getHeadings({ data }: InferPageType<typeof source>): string[] {
60+
return data.toc.map((item) => item.url.slice(1));
61+
}
62+
63+
function getFiles() {
64+
const promises = source.getPages().map(
65+
async (page): Promise<FileObject> => ({
66+
path: page.absolutePath,
67+
content: await page.data.getText('raw'),
68+
url: page.url,
69+
data: page.data,
70+
}),
71+
);
72+
73+
return Promise.all(promises);
74+
}
75+
76+
void checkLinks();
77+
```
78+
79+
## Running Lint
80+
81+
<Callout type="info">
82+
To access the `source` object outside of app runtime, configure [Fumadocs MDX Loader](/docs/mdx/loader/bun) first.
83+
</Callout>
84+
85+
Then, run the script to validate links:
86+
87+
```bash
88+
bun ./scripts/lint.ts
89+
```
90+
91+
<Callout type="warn">
92+
For Node.js, you might need to configure `tsconfig-paths`, TypeScript transpiling, and [Fumadocs MDX Loader](/docs/mdx/loader/node).
93+
94+
Without special reasons, using Bun or [`tsx`](https://github.com/privatenumber/tsx) would be simpler.
95+
</Callout>

content/docs/meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"index",
55
"getting-started",
66
"components",
7+
"integrations",
78
"development-plan"
89
]
910
}

0 commit comments

Comments
 (0)