Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('isInternalUrl', () => {
expect(isInternalUrl('https://foo.com')).toBeFalsy();
});

it('returns false for whatever protocol links', () => {
it('returns false for relative protocol links', () => {
expect(isInternalUrl('//foo.com')).toBeFalsy();
});

Expand All @@ -43,4 +43,50 @@ describe('isInternalUrl', () => {
it('returns false for undefined links', () => {
expect(isInternalUrl(undefined)).toBeFalsy();
});

describe('custom scheme links', () => {
it('returns true for invalid protocol schemes', () => {
expect(isInternalUrl('+customScheme://')).toBeTruthy();
expect(isInternalUrl('+customScheme://whatever')).toBeTruthy();
expect(isInternalUrl('+customScheme:whatever')).toBeTruthy();

expect(isInternalUrl('.customScheme://')).toBeTruthy();
expect(isInternalUrl('.customScheme://whatever')).toBeTruthy();
expect(isInternalUrl('.customScheme:whatever')).toBeTruthy();

expect(isInternalUrl('-customScheme://')).toBeTruthy();
expect(isInternalUrl('-customScheme://whatever')).toBeTruthy();
expect(isInternalUrl('-customScheme:whatever')).toBeTruthy();

expect(isInternalUrl('custom_scheme://')).toBeTruthy();
expect(isInternalUrl('custom_scheme://whatever')).toBeTruthy();
expect(isInternalUrl('custom_scheme:whatever')).toBeTruthy();

expect(isInternalUrl('custom scheme://')).toBeTruthy();
expect(isInternalUrl('custom scheme://whatever')).toBeTruthy();
expect(isInternalUrl('custom scheme:whatever')).toBeTruthy();

expect(isInternalUrl('custom$scheme://')).toBeTruthy();
expect(isInternalUrl('custom$scheme://whatever')).toBeTruthy();
expect(isInternalUrl('custom$scheme:whatever')).toBeTruthy();
});

it('returns false valid protocol schemes', () => {
expect(isInternalUrl('customScheme://')).toBeFalsy();
expect(isInternalUrl('customScheme://whatever')).toBeFalsy();
expect(isInternalUrl('customScheme:whatever')).toBeFalsy();

expect(isInternalUrl('custom-scheme://')).toBeFalsy();
expect(isInternalUrl('custom-scheme://whatever')).toBeFalsy();
expect(isInternalUrl('custom-scheme:whatever')).toBeFalsy();

expect(isInternalUrl('custom.scheme://')).toBeFalsy();
expect(isInternalUrl('custom.scheme://whatever')).toBeFalsy();
expect(isInternalUrl('custom.scheme:whatever')).toBeFalsy();

expect(isInternalUrl('custom-sch.eme+-.://')).toBeFalsy();
expect(isInternalUrl('custom-sch.eme+-.://whatever')).toBeFalsy();
expect(isInternalUrl('custom-sch.eme+-.:whatever')).toBeFalsy();
});
});
});
5 changes: 4 additions & 1 deletion packages/docusaurus/src/client/exports/isInternalUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
* LICENSE file in the root directory of this source tree.
*/

// Poor man's protocol detection
// Spec: https://datatracker.ietf.org/doc/html/rfc3986#section-3.1
// In particular: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
export function hasProtocol(url: string): boolean {
return /^(?:\w*:|\/\/)/.test(url);
return /^(?:[A-Za-z][A-Za-z\d+.-]*:|\/\/)/.test(url);
}

export default function isInternalUrl(url?: string): boolean {
Expand Down
14 changes: 6 additions & 8 deletions website/_dogfooding/_pages tests/markdown-tests-mdx.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -360,29 +360,27 @@ This is a test page to see if Docusaurus Markdown features are working properly
See [#3337](https://github.com/facebook/docusaurus/issues/3337)

- [/someFile.pdf](/someFile.pdf)

- [/someFile.xyz](/someFile.xyz)

- [/image with space.png](</image with spaces.png>)

- [@site/\_dogfooding/\_asset-tests/someFile.pdf](@site/_dogfooding/_asset-tests/someFile.pdf)

- [@site/\_dogfooding/\_asset-tests/someFile.xyz](@site/_dogfooding/_asset-tests/someFile.xyz)

- [@site/\_dogfooding/\_asset-tests/image with space.png](<@site/_dogfooding/_asset-tests/image with spaces.png>)

### Linking to non-SPA page hosted within website

See [#3309](https://github.com/facebook/docusaurus/issues/3309)

- [pathname:///dogfooding/javadoc](pathname:///dogfooding/javadoc)

- [pathname:///dogfooding/javadoc/index.html](pathname:///dogfooding/javadoc/index.html)

- [pathname://../dogfooding/javadoc](pathname://../dogfooding/javadoc)

- [pathname://../dogfooding/javadoc/index.html](pathname://../dogfooding/javadoc/index.html)

### Linking to non-SPA paths with custom schemes

- [customScheme://whatever](customScheme://whatever)
- [custom-scheme://whatever](custom-scheme://whatever)
- [custom-sch.eme+-.://whatever](custom-sch.eme+-.://whatever)

### Linking to non-SPA page with Link component

See [#9758](https://github.com/facebook/docusaurus/issues/9758), these external urls should not be reported by the broken links checker:
Expand Down