Skip to content

Commit 99cb7de

Browse files
authored
feat: external relative link (#569)
* feat: external relative link * chore: remove p tag outside link * tweak: link ext * tweak: Link
1 parent fada2f9 commit 99cb7de

File tree

3 files changed

+65
-6
lines changed

3 files changed

+65
-6
lines changed

src/components/Layout/MDXContent.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as React from "react";
2-
import { Link } from "gatsby";
32

43
import { MDXProvider } from "@mdx-js/react";
54
import { MDXRenderer } from "gatsby-plugin-mdx";
@@ -17,10 +16,7 @@ import { PathConfig, FrontMatter, BuildType } from "shared/interface";
1716
import { useTotalContributors } from "components/Contributors";
1817
import replaceInternalHref from "shared/utils/anchor";
1918
import { Pre } from "components/MDXComponents/Pre";
20-
import {
21-
CustomContent,
22-
useCustomContent,
23-
} from "components/MDXComponents/CustomContent";
19+
import { useCustomContent } from "components/MDXComponents/CustomContent";
2420
import { getPageType } from "shared/utils";
2521

2622
export default function MDXContent(props: {
@@ -87,7 +83,6 @@ export default function MDXContent(props: {
8783
<MDXProvider
8884
components={{
8985
...MDXComponents,
90-
Link,
9186
pre: Pre,
9287
CustomContent: CustomContentWithPageType,
9388
}}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { Link } from "gatsby";
2+
3+
export const TargetLink = (props: { to: string; [key: string]: any }) => {
4+
const { to } = props;
5+
const { pathWithHash, query } = parsePathWithQuery(to);
6+
const newProps = { ...props };
7+
const isTargetBlank = query["target"] === "_blank";
8+
9+
if (isTargetBlank) {
10+
newProps.target = "_blank";
11+
newProps.to = pathWithHash;
12+
newProps.rel = "noopener noreferrer";
13+
}
14+
15+
return (
16+
<Link
17+
{...newProps}
18+
onClick={(e) => {
19+
if (isTargetBlank) {
20+
e.preventDefault();
21+
window.open((e.target as HTMLAnchorElement).href, "_blank");
22+
}
23+
}}
24+
/>
25+
);
26+
};
27+
28+
const parsePathWithQuery = (path: string) => {
29+
const result: { query: { [k: string]: string }; pathWithHash: string } = {
30+
query: {},
31+
pathWithHash: "",
32+
};
33+
34+
const [pathPart, hashPart] = path.split("#");
35+
36+
let actualPath = pathPart;
37+
let hash = "";
38+
let queryPart = "";
39+
40+
if (hashPart && hashPart.includes("?")) {
41+
const [actualHash, query] = hashPart.split("?");
42+
hash = actualHash;
43+
queryPart = query;
44+
} else {
45+
hash = hashPart || "";
46+
47+
const isQueryInPath = pathPart.includes("?");
48+
actualPath = isQueryInPath ? pathPart.split("?")[0] : pathPart;
49+
queryPart = isQueryInPath ? pathPart.split("?")[1] : "";
50+
}
51+
52+
if (queryPart) {
53+
const params = new URLSearchParams(queryPart);
54+
for (const [key, value] of params.entries()) {
55+
result.query[key] = value;
56+
}
57+
}
58+
59+
result.pathWithHash = actualPath + (hash ? `#${hash}` : "");
60+
61+
return result;
62+
};

src/components/MDXComponents/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ export {
3232
DevToolGroup,
3333
DevToolCard,
3434
} from "components/MDXComponents/developer";
35+
36+
export { TargetLink as Link } from "./Link";

0 commit comments

Comments
 (0)