블로그 미리보기에 Hashnode의 API 사용

나는 최근에 Hashnode에서 내 블로그를 호스팅하기로 결정하여 코드 작성에 더 많은 시간을 할애하고 코드 관리는 덜 할 수 있었습니다. 나는 여전히 내 포트폴리오 웹사이트에서 가장 최근 게시물에 대한 미리보기와 링크를 표시하고 싶었습니다. 운 좋게도 Hashnode는 가장 최근 게시물을 가져올 수 있는 GraphQL API를 제공합니다.

API



api.hashnode.com 에서 API 플레이그라운드 및 문서에 액세스할 수 있습니다. 이를 통해 쿼리를 개발하고 원하는 정확한 응답을 제공할 수 있습니다. 문서를 읽은 후 내 포트폴리오 페이지에 미리 보기를 표시하는 데 필요한 모든 것을 제공하는 쿼리를 작성했습니다.

{
  user(username: "CodeByCorey") {
    publication {
      posts(page: 0) {
        slug
        title
        brief
        coverImage
        replyCount
        totalReactions
      }
    }
  }
}


  • user(username: "CodeByCorey") : 내 사용자에 대한 쿼리
  • publication : 내 블로그 게시에 대한 모든 정보를 포함합니다
  • .
  • posts(page: 0) : 첫 페이지의 모든 게시물을 반환합니다.
  • slug : 블로그 게시물에 대한 링크를 만들 수 있습니다
  • .
  • title : 내 게시물의 제목을 표시하기 위해
  • brief : 게시물에 있는 텍스트의 작은 스니펫입니다
  • .
  • coverImage : 미리보기에서 표지 이미지를 표시할 수 있도록
  • replyCount : 게시물의 댓글 수
  • totalReactions : 내 게시물에 대한 총 반응 수



  • 쿼리 사용



    이제 쿼리가 있으므로 이를 사용하여 데이터를 가져올 차례입니다. 내 Next.js 앱에 posts.ts 라는 새 lib 파일을 만들었습니다. 가져오기를 사용하여 API를 호출하고 쿼리를 요청 본문에 전달했습니다.

    const query: string = `
      {
        user(username: "CodeByCorey") {
          publication {
            posts(page: 0) {
              slug
              title
              brief
              coverImage
              replyCount
              totalReactions
            }
          }
        }
      }
    `;
    export const fetchPosts = async () => {
      const resp: Response = await fetch('https://api.hashnode.com', {
        method: 'POST',
        headers: {
          'Content-type': 'application/json',
        },
        body: JSON.stringify({ query }),
      })
      const hashnodeResponse = await resp.json();
      return hashnodeResponse.data.user.publication.posts;
    };
    


    마지막 세 개의 게시물만 표시하고 싶었습니다. 응답을 제한하기 위해 게시물을 슬라이스하는 또 다른 기능을 추가했습니다. 이것

    export const fetchThreeMostRecentPost = async() => {
      const posts = await fetchPosts();
      return posts.slice(0, 3);
    }
    


    내 컨테이너 구성 요소 내에서 Next.jsgetStaticProps 함수를 사용하여 게시물을 가져와 내 구성 요소의 소품으로 전달했습니다. Hashnode에 새 게시물을 작성할 때 HTML을 자동으로 재생성하도록 revalidate 설정을 추가했습니다.

    export async function getStaticProps() {
    
      const posts = await fetchThreeMostRecentPosts();
      return {
        props: {
          posts
        },
        revalidate: 60
      };
    }
    


    이제 모든 데이터를 가져와 소품으로 전달했으므로 이제 내 구성 요소의 스타일을 지정해야 합니다. 포트폴리오 웹사이트에 Tailwind CSS를 사용하고 있습니다. 다음은 RecentBlogPosts 구성 요소입니다.

    export default function RecentBlogPosts({ posts }: Props) {
      return (
        <div className="container mx-auto py-12 text-gray-800">
          <h2 className="text-center text-2xl md:text-4xl pb-6">Recent Blog Posts</h2>
          <div className="flex flex-wrap justify-center">
            {posts.map((post, index) => (
              <a key={index} href={`https://blog.coreyodonnell.tech/${post.slug}`} className="md:w-2/3 lg:w-1/3 px-5 my-2">
                <BlogPreview post={post} />
              </a>
            ))}
          </div>
          <div className="flex flex-wrap justify-center">
            <a
              className="text-green-500 font-semibold hover:text-gray-800 py-4 px-4 rounded"
              href="https://blog.coreyodonnell.tech/"
            >
              View all posts
            </a>
          </div>
        </div>
      );
    }
    


    블로그미리보기:

    export default function BlogPreview({ post }: Props) {
      return (
        <div className="h-full border-2 border-gray-200 rounded-lg flex flex-col justify-between">
          <div className="w-full">
            <img className="lg:h-48 md:h-36 w-full object-cover object-center" src={post.coverImage} alt="blog" />
            <div className="p-6">
              <h1 className="title-font text-lg font-medium text-gray-900 mb-3">{post.title}</h1>
              <p className="leading-relaxed mb-3 text-gray-600">{post.brief}</p>
            </div>
          </div>
          <div className="flex items-center flex-wrap p-6">
            <span className="text-indigo-500 inline-flex items-center md:mb-2 lg:mb-0">
              Learn More
              <svg
                className="w-4 h-4 ml-2"
                viewBox="0 0 24 24"
                stroke="currentColor"
                strokeWidth="2"
                fill="none"
                strokeLinecap="round"
                strokeLinejoin="round"
              >
                <path d="M5 12h14"></path>
                <path d="M12 5l7 7-7 7"></path>
              </svg>
            </span>
            <span className="text-gray-600 mr-3 inline-flex items-center lg:ml-auto md:ml-0 ml-auto leading-none text-sm pr-3 py-1 border-r-2 border-gray-300">
              <svg className="w-4 h-4 mr-1" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
                />
              </svg>
              {post.totalReactions}
            </span>
            <span className="text-gray-600 inline-flex items-center leading-none text-sm">
              <svg className="w-4 h-4 mr-1" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"
                />
              </svg>
              {post.replyCount}
            </span>
          </div>
        </div>
      );
    }
    
    


    구성 요소 스타일 지정 후의 최종 결과:



  • 해시노드 API - api.hashnode.com
  • Next.js 문서 - https://nextjs.org/
  • portfolio page - Source Code (진행 중인 작업)
  • 을 확인할 수 있습니다.
  • 기술 및 재택 근무에 대한 임의 게시물을 보려면 저를 팔로우하세요.
  • 좋은 웹페이지 즐겨찾기