Gatsby의 Sanity에서 앵커 링크
25032 단어 podcastjavascriptbeginnerswebdev
TL;DR version is make sure you implement
onRouteUpdate
andshouldUpdateScroll
ingatsby-browser.js
.
그렇다면 앵커 링크는 무엇입니까?
앵커 링크는 HTML에서 동일한 페이지 내에서 탐색하는 방법입니다. 그것들을 생각하는 가장 쉬운 방법은 목차 또는 페이지의 책갈피와 같습니다.
#
형식의 헤더 태그가 있는 마크다운 페이지에서 자주 사용되는 앵커를 볼 수 있습니다. 이제 일반 헤더 태그가 링크를 가지려면 다음과 같이 프런트 엔드에서 링크 태그로 래핑해야 합니다. <a href="#anchor"><h2>Headline Link</h2></a>
. 이 페이지의 코드를 검사하면 블로그가 마크다운으로 작성되고 HTML로 변환되는 것과 같은 예를 볼 수 있습니다.Sanity.io
이것이 Sanity.io와 어떻게 작동합니까?
Sanity은 헤드리스 콘텐츠 기반 CMS입니다. rich text editor 을 작성하면 portable text 이 생성됩니다. 따라서 마크다운과 달리 헤더
#
항목을 변환할 필요는 없지만 휴대용 텍스트를 Gatsby가 이해할 수 있는 것으로 직렬화해야 합니다. Sanity.io를 사용하여 사이트를 만드는 방법에 대해 너무 깊이 파고들지는 않겠습니다.훌륭한 가이드 Sanity Gatsby 블로그 확장
Sanity.io의 Gatsby 는 빠르게 시작하고 실행하는 방법에 대한 훌륭한 출발점입니다. 이를 사용한 다음 원하는 대로 기능을 확장할 수 있습니다. 예제에는 아래와 비슷한 게시물 파일이 있습니다. 우리가 정말로 신경 쓰는 것은
gatsby-source-sanity
행입니다.import React from "react";
import PortableText from "./portableText";
import Card from "../Card";
export default (props) => {
const { _rawBody, authors, categories } = props;
return(
<article className="flex flex-col w-full max-w-xl md:max-w-1xl md:max-w-2xl lg:max-w-3xl xl:max-w-6xl m-2 md:max-m-8 md:max-m-8 lg:max-m-8 xl:m-8">
<div className="w-full">
<Card {...props} />
</div>
<section className="markdown bg-white w-full rounded mt-4 p-4">
<div>{_rawBody && <PortableText blocks={_rawBody} />}</div>
<div>
<aside>
{categories && (
<div>
<h3>Categories</h3>
<ul>
{categories.map(category => (
<li key={category._id}>{category.title}</li>
))}
</ul>
</div>
)}
</aside>
</div>
</section>
</article>
)}
이것은 blog example 을 사용하는 간단한 반응 구성 요소입니다. 여기서 가장 중요한 부분은 직렬 변환기를 허용하고 Sanity.io의 graphql에서 수신할 블록 기반 PortableText에 많은 사용자 정의를 추가할 수 있다는 것입니다.
import React from "react";
import clientConfig from "../../../client-config";
import BasePortableText from "@sanity/block-content-to-react";
import serializers from "../graphql/serializers";
const PortableText = ({ blocks }) => {
return(
<BasePortableText
blocks={blocks}
serializers={{...serializers}}
{...clientConfig.sanity} />
)
};
export default PortableText;
@sanity/block-content-to-react Sanity.io 직렬 변환기
직렬 변환기의 가장 큰 장점은 Sanity.io에서 오는 다양한 유형을 처리하려는 사용자 지정 React 구성 요소를 제공할 수 있다는 것입니다.
import React from "react";
import Figure from "./Figure";
import Code from "./Code";
import Img from "./Img";
import Block from "./Block";
const serializers = {
types: {
authorReference: ({ node }) => <span>{node.author.name}</span>,
mainImage: Figure,
code: Code,
img: Img,
block: Block
},
};
export default serializers;
재미있고 간단한 예는
<div>{_rawBody && <PortableText blocks={_rawBody} />}</div>
입니다. 이 인라인을 많이 추가할 수 있지만
이미지 조작을 사용하여 이미지에 원하는 대로 효과를 적용할 계획입니다. 그래서 노드를 가져와 해당 대체 텍스트가 있는 간단한 img 태그를 출력하는 img
라는 간단한 구성 요소를 추가했습니다.import React from "react";
export default ({ node }) => {
const { asset } = node;
return <img src={asset.src} alt={asset.alt} />;
};
이제 portableText와 함께 나타나는 모든
Img
유형 항목에 대해서도 마찬가지입니다. 우리는 Sanity.io의 멋진block
을 사용하고 있기 때문에 여기에서 실제로 많은 작업을 수행할 필요는 없지만 다시 한 번 게으른 개발자이므로 모든 제목에 앵커 태그가 연결되도록 만들고 싶지만 portableText는 아래와 같이 보입니다. :그래서 이를 실현하기 위해 우리는 위에 Sanity.io가 훌륭한 설정 방법cloudinary's을 가지고 있는 직렬 변환기@sanity/block-content-to-react
를 추가했습니다. My Block은 매우 유사해 보이지만 이러한 각 제목(현재는 h2 및 h3) 내부에 Gatsby Link 태그를 설정하고 있습니다.import React from "react";
import { IoMdLink } from "react-icons/io/";
import { Link } from "gatsby";
const slugs = require(github-slugger)()
export default (props) => {
slugs.reset();
const style = props.node.style || 'normal';
// If Heading Level add Anchor Link
if (typeof location !== undefined && /^h\d/.test(style)) {
const level = style.replace(/[^\d]/g, '')
const slug = slugs.slug(props.children[0], false)
switch (level) {
case 'h3':
return <h3 id={slug} className="flex">{props.children}<Link to={${location.pathname}#${slug}}><div className="py-1 pl-1 rotateIn"><IoMdLink /></div></Link></h3>
default:
return <h2 id={slug} className="flex">{props.children}<Link to={${location.pathname}#${slug}}><div className="py-1 pl-1 rotateIn"><IoMdLink /></div></Link></h2>
}
}
return style === 'blockquote'
? <blockquote>{props.children}</blockquote>
: <p>{props.children}</p>
};
예시 Gatsby 앵커 링크 추가
이제 Knut Melvær는 프런트 엔드에 링크를 추가하는 방법을 자세히 설명하는 훌륭한 가이드 를 가지고 있지만, 저는 상당히 게으른 개발자이고 모든 앵커 링크를 수동으로 선택하고 추가하고 싶지 않습니다. 그래서 위의 방법을 사용했습니다. Internal and external links을 사용하는 마크다운 파일을 사용하여 동일한 접근 방식을 만들 수 있습니다. 내가 찾은 한 가지 누락된 부분은 Gatsby에서 페이지 내의 올바른 위치로 스크롤하는 것입니다. 이를 위해 Gatsby는 몇 가지 멋진 기능gatsby-remark-autolink-headers을 제공합니다. 페이지가 처음 로드될 때 스크롤이 발생하려면
block: Block
를 사용해야 합니다. 이렇게 하면 위치를 사용하고 앵커 링크인 onRouteUpdate
의 존재를 확인할 수 있습니다. 또한 내부 링크를 선택해도 경로 업데이트가 트리거되지 않으므로hash
구현했습니다. 따라서 이는 refresh.gatsby-browser.js 없이 필요했습니다./**
* Implement Gatsby's Browser APIs in this file.
*
* See: https://www.gatsbyjs.org/docs/browser-apis/
*/
// You can delete this file if you're not using it
exports.onRouteUpdate = ({location}) => {
anchorScroll(location);
return true;
};
exports.shouldUpdateScroll = ({
routerProps: { location },
getSavedScrollPosition
}) => {
anchorScroll(location);
return true;
}
function anchorScroll(location){
// Check for location so build does not fail
if (location && location.hash) {
setTimeout(() => {
// document.querySelector(${location.hash}).scrollIntoView({ behavior: 'smooth', block: 'start' });
const item = document.querySelector(${location.hash}).offsetTop;
const mainNavHeight = document.querySelector(nav).offsetHeight;
window.scrollTo({top: item - mainNavHeight, left: 0, behavior: 'smooth'});
}, 0);
}
}
브라우저 API 최종 결과
새로 고침 및 내부 링크 클릭 시 멋진 부드러운 스크롤 화면.
Reference
이 문제에 관하여(Gatsby의 Sanity에서 앵커 링크), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/codingcatdev/anchor-links-from-sanity-in-gatsby-320n텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)