diff --git a/quartz/plugins/transformers/links.ts b/quartz/plugins/transformers/links.ts index 50d2d1a0a..1ba0c8e58 100644 --- a/quartz/plugins/transformers/links.ts +++ b/quartz/plugins/transformers/links.ts @@ -21,6 +21,7 @@ interface Options { prettyLinks: boolean openLinksInNewTab: boolean lazyLoad: boolean + externalLinkIcon: boolean } const defaultOptions: Options = { @@ -28,6 +29,7 @@ const defaultOptions: Options = { prettyLinks: true, openLinksInNewTab: false, lazyLoad: false, + externalLinkIcon: true, } export const CrawlLinks: QuartzTransformerPlugin | undefined> = (userOpts) => { @@ -55,7 +57,29 @@ export const CrawlLinks: QuartzTransformerPlugin | undefined> = ) { let dest = node.properties.href as RelativeURL const classes = (node.properties.className ?? []) as string[] - classes.push(isAbsoluteUrl(dest) ? "external" : "internal") + const isExternal = isAbsoluteUrl(dest) + classes.push(isExternal ? "external" : "internal") + + if (isExternal && opts.externalLinkIcon) { + node.children.push({ + type: "element", + tagName: "svg", + properties: { + class: "external-icon", + viewBox: "0 0 512 512", + }, + children: [ + { + type: "element", + tagName: "path", + properties: { + d: "M320 0H288V64h32 82.7L201.4 265.4 178.7 288 224 333.3l22.6-22.6L448 109.3V192v32h64V192 32 0H480 320zM32 32H0V64 480v32H32 456h32V480 352 320H424v32 96H64V96h96 32V32H160 32z", + }, + children: [], + }, + ], + }) + } // Check if the link has alias text if ( diff --git a/quartz/styles/base.scss b/quartz/styles/base.scss index 607749aa1..16a96122e 100644 --- a/quartz/styles/base.scss +++ b/quartz/styles/base.scss @@ -59,6 +59,7 @@ a { text-decoration: none; transition: color 0.2s ease; color: var(--secondary); + display: inline-block; &:hover { color: var(--tertiary) !important; @@ -76,6 +77,16 @@ a { padding: 0; } } + + &.external .external-icon { + vertical-align: bottom; + height: 1ex; + margin: 0 0.15em; + + > path { + fill: var(--dark); + } + } } .desktop-only {