Internal links are not target=_blank by default (#1037)
* feat: internal links are not target=_blank by default * feat: use <Link> --------- Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
This commit is contained in:
parent
4633e8eb5e
commit
5be6df0266
|
@ -19,7 +19,7 @@ import { rehypeInlineCodeProperty } from '@/lib/md'
|
|||
import { Button } from 'react-bootstrap'
|
||||
import { useRouter } from 'next/router'
|
||||
import Link from 'next/link'
|
||||
import { UNKNOWN_LINK_REL } from '@/lib/constants'
|
||||
import { SSR, UNKNOWN_LINK_REL } from '@/lib/constants'
|
||||
import isEqual from 'lodash/isEqual'
|
||||
|
||||
export function SearchText ({ text }) {
|
||||
|
@ -178,6 +178,8 @@ export default memo(function Text ({ rel, imgproxyUrls, children, tab, itemId, o
|
|||
// If [text](url) was parsed as <a> and text is not empty and not a link itself,
|
||||
// we don't render it as an image since it was probably a conscious choice to include text.
|
||||
const text = children[0]
|
||||
const url = !href.startsWith('/') && new URL(href)
|
||||
const internalURL = SSR ? 'https://stacker.news' : window.location.origin
|
||||
if (!!text && !/^https?:\/\//.test(text)) {
|
||||
if (props['data-footnote-ref'] || typeof props['data-footnote-backref'] !== 'undefined') {
|
||||
return (
|
||||
|
@ -189,6 +191,16 @@ export default memo(function Text ({ rel, imgproxyUrls, children, tab, itemId, o
|
|||
</Link>
|
||||
)
|
||||
}
|
||||
if (href.startsWith('/') || url.origin === internalURL) {
|
||||
return (
|
||||
<Link
|
||||
id={props.id}
|
||||
href={href}
|
||||
>
|
||||
{text}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
return (
|
||||
// eslint-disable-next-line
|
||||
<a id={props.id} target='_blank' rel={rel ?? UNKNOWN_LINK_REL} href={href}>{text}</a>
|
||||
|
@ -198,7 +210,7 @@ export default memo(function Text ({ rel, imgproxyUrls, children, tab, itemId, o
|
|||
try {
|
||||
const linkText = parseInternalLinks(href)
|
||||
if (linkText) {
|
||||
return <a target='_blank' href={href} rel='noreferrer'>{linkText}</a>
|
||||
return <Link href={href}>{linkText}</Link>
|
||||
}
|
||||
} catch {
|
||||
// ignore errors like invalid URLs
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { SSR } from './constants'
|
||||
|
||||
export function ensureProtocol (value) {
|
||||
if (!value) return value
|
||||
value = value.trim()
|
||||
|
@ -28,11 +30,12 @@ export function removeTracking (value) {
|
|||
*/
|
||||
export function parseInternalLinks (href) {
|
||||
const url = new URL(href)
|
||||
const internalURL = SSR ? 'https://stacker.news' : window.location.origin
|
||||
const { pathname, searchParams } = url
|
||||
// ignore empty parts which exist due to pathname starting with '/'
|
||||
const emptyPart = part => !!part
|
||||
const parts = pathname.split('/').filter(emptyPart)
|
||||
if (parts[0] === 'items' && /^[0-9]+$/.test(parts[1])) {
|
||||
if (parts[0] === 'items' && /^[0-9]+$/.test(parts[1]) && url.origin === internalURL) {
|
||||
const itemId = parts[1]
|
||||
// check for valid item page due to referral links like /items/123456/r/ekzyis
|
||||
const itemPages = ['edit', 'ots', 'related']
|
||||
|
|
Loading…
Reference in New Issue