React/Gatsby/Next.js 환경에서 외부링크와 내부링크 자동으로 인식
react-router-dom & next/linkReact와 Next.js는 a 태그(anchor)를 만났을 때 내부 링크인 경우에 새로 페이지를 로딩하는 게 아닌, 다른 부분만 DOM을 업데이트 하는 방식을 취해서 로딩 속도를 개선합니다.
그러기 위해서 Link를 사용합니다.
주의
html의 와는 전혀 다른 기능입니다.
React / Gatsby
// src/components/AnchorLink.js
import React from 'react'
import PropTypes from 'prop-types'
// React일 때는 'gatsby' 대신 'react-router-dom' 사용
import { Link } from 'gatsby'
const domainRegex = /http[s]*:\/\/[www.]*domain\.com[/]?/
const AnchorLink = ({ href, ...rest }) => {
const sameDomain = domainRegex.test(href)
if (sameDomain) {
href = href.replace(domainRegex, '/')
}
if (href.startsWith('/')) {
return <Link to={href} {...rest} />
}
if (!href.startsWith('http')) {
return <a href={href} {...rest} />
}
return (
<a
href={href}
target='_blank'
rel='noopener noreferrer nofollow'
{...rest}
/>
)
}
LinkButton.propTypes = {
href: PropTypes.string.isRequired,
}
export default AnchorLink;
Next.js
JavaScript
// /components/AnchorLink.js
import PropTypes from 'prop-types'
import Link from 'next/link'
const domainRegex = /http[s]*:\/\/[www.]*domain\.com[/]?/
const AnchorLink = ({ href, ...rest }) => {
const sameDomain = domainRegex.test(href)
if (sameDomain) {
href = href.replace(domainRegex, '/')
}
if (href.startsWith('/')) {
return <Link href={href} {...rest} />
}
if (!href.startsWith('http')) {
return <a href={href} {...rest} />
}
return (
<a
href={href}
target='_blank'
rel='noopener noreferrer nofollow'
{...rest}
/>
)
}
LinkButton.propTypes = {
href: PropTypes.string.isRequired,
}
export default AnchorLink;
TyepScript
import Link from 'next/link';
interface AnchorLinkProps {
href: string;
[key: string]: any;
}
const domainRegex = /http[s]*:\/\/[www.]*domain\.com[/]?/;
const AnchorLink: React.FC<AnchorLinkProps> = ({ href, ...rest }) => {
const sameDomain = domainRegex.test(href);
let h = href;
if (sameDomain) {
h = h.replace(domainRegex, '/');
}
if (href.startsWith('/')) {
return <Link href={h} {...rest} />;
}
if (!h.startsWith('http')) {
return <a href={h} {...rest} />;
}
return <a href={h} target="_blank" rel="noopener noreferrer nofollow" {...rest} />;
};
export default AnchorLink;
응용
React/Gatsby/Next.js 경로만 다르고 사용하는 방법은 동일
<AnchorLink href=`링크 경로`>헬로 월드</AnchorLink>
- 바로 위 코드에서 href 값이 http 또는 https 프로토콜이 사용되면 자동으로 target과 rel이 붙습니다.
- emotion에서 LinkButton에 스타일링을 하고싶다면 AnchorLink를 감싸는 태그에 스타일링을 지정해서 사용해야 합니다.
- CSS/SASS에서 내부 링크인지 외부 링크인지에 따라서 스타일링을 다르게 주고 싶다면 a:not([target]) { ... } 이렇게
:not
선택자를 사용하세요.