인프런 커뮤니티 질문&답변

최정훈님의 프로필 이미지

작성한 질문수

React 기반 Gatsby로 기술 블로그 개발하기 v2

게시글 렌더링 커스터마이징하기 (2)

code 강조가 안됨니다..

해결된 질문

작성

·

135

0

코드블럭 테스트

language::typescript

export const { auth, signIn, signOut, handlers } = NextAuth({

등등을 존재하는데

아래와같이 코드는 작성했는데 코드 강조가 안되고있습니다. 뭐가문제일까요?

import React from 'react'
import {
  ContentfulRichTextGatsbyReference,
  renderRichText,
} from 'gatsby-source-contentful/rich-text'
import { getImage } from 'gatsby-plugin-image'
import { NodeRenderer, Options } from '@contentful/rich-text-react-renderer'
import { BLOCKS, INLINES, MARKS } from '@contentful/rich-text-types'
import {
  Blockquote,
  Heading,
  Image,
  HorizontalRule,
  OrderedList,
  UnorderedList,
  Link,
  Code,
} from './node'

export const HEADERS = [
  BLOCKS.HEADING_1,
  BLOCKS.HEADING_2,
  BLOCKS.HEADING_3,
] as const
const CODE_METADATA_REGEX = /^language::(\w+)/

const options: Options = {
  renderMark: {
    [MARKS.CODE]: text => {
      const isBlock = !!text && CODE_METADATA_REGEX.test(text.toString())

      if (!isBlock) return <Code>{text}</Code>
      else
        return (
          <Code
            isBlock
            className={`language-${
              CODE_METADATA_REGEX.exec(text.toString())?.[1]
            }`}
          >
            {text.toString().replace(CODE_METADATA_REGEX, '').trimStart()}
          </Code>
        )
    },
  },
  renderNode: {
    ...HEADERS.reduce<{ [block: string]: NodeRenderer }>((nodes, header) => {
      nodes[header] = (node, children) => (
        <Heading type={header}>{children}</Heading>
      )

      return nodes
    }, {}),
    [BLOCKS.OL_LIST]: (_node, children) => (
      <OrderedList>{children}</OrderedList>
    ),
    [BLOCKS.UL_LIST]: (_node, children) => (
      <UnorderedList>{children}</UnorderedList>
    ),
    [BLOCKS.HR]: () => <HorizontalRule />,
    [BLOCKS.QUOTE]: (_node, children) => <Blockquote>{children}</Blockquote>,
    [BLOCKS.EMBEDDED_ASSET]: node => {
      const { gatsbyImageData, description } = node.data.target
      const image = getImage(gatsbyImageData)

      if (image) return <Image image={image} alt={description} />
    },
    [INLINES.HYPERLINK]: (node, children) => (
      <Link
        href={node.data.uri as string}
        target="_blank"
        rel="noopener noreferrer"
      >
        {children}
      </Link>
    ),
  },
}

export default function useRenderRichText({
  raw,
  references,
}: Queries.ContentfulPostContent) {
  if (!raw) return null

  return renderRichText(
    {
      raw,
      references: references as unknown as ContentfulRichTextGatsbyReference[],
    },
    options,
  )
}

import React from 'react' import { GatsbyBrowser } from 'gatsby' import Layout from './src/components/common/Layout' import 'prismjs/themes/prism-tomorrow.min.css' export const wrapPageElement: GatsbyBrowser['wrapPageElement'] = ({ element, props, }) => { return <Layout {...props}>{element}</Layout> }

import React from 'react'
import { GatsbyBrowser } from 'gatsby'
import Layout from './src/components/common/Layout'
import 'prismjs/themes/prism-tomorrow.min.css'

export const wrapPageElement: GatsbyBrowser['wrapPageElement'] = ({
  element,
  props,
}) => {
  return <Layout {...props}>{element}</Layout>
}

import React, { useEffect } from 'react' import styled from 'styled-components' import { TPostBodyProps } from '../../types/PostBody' import Prism from 'prismjs' import 'prismjs/components/prism-typescript' import useRenderRichText from '../../hooks/useRenderRichText' const Wrapper = styled.div` position: relative; display: grid; grid-template-columns: 1fr 220px; grid-gap: 30px; justify-content: space-between; align-items: flex-start; padding-top: 100px; ` const Content = styled.div` overflow: auto; display: flex; flex-direction: column; gap: 100px; font-size: 16px; line-height: 2; word-break: break-word; ` export default function PostBody({ content }: TPostBodyProps) { const richText = useRenderRichText(content) useEffect(() => { Prism.highlightAll() }, []) return ( <Wrapper> <Content> <div id="content">{richText}</div> {/* 댓글 컴포넌트가 들어갈 자리 */} </Content> {/* 플로팅 목차 컴포넌트가 들어갈 자리 */} </Wrapper> ) }

답변 3

1

주현도님의 프로필 이미지
주현도
지식공유자

Contentful 게시글을 렌더링하는 과정에서 모든 요소들이 각각 p 태그로 래핑되는데, 해당 강의에서 코드를 표현하기 위한 목적으로 사용되는 pre 태그 또한 p 태그로 래핑됩니다. 그래서 p 태그 내에 pre 태그가 위치하여 해당 에러가 발생하는데, 동작 과정에서 문제가 되는 부분은 없기에 무시하고 넘어가셔도 상관없습니다!

최정훈님의 프로필 이미지
최정훈
질문자

감사합니다. 해당 부부은 타입으로 체크하여 p 태그를 삭제하는 방식으로 했습니다!! 도와주셔서 감사합니다!

0

최정훈님의 프로필 이미지
최정훈
질문자

감사합니다 해결되었습니다!!

그런데 해당 부분이 해결되고나니


head-export-handler-for-browser.js:72
Warning: validateDOMNesting(...): <pre> cannot appear as a descendant of <p>.

이러한 에러가 발생하는데 뭐가 문제일까요?

0

주현도님의 프로필 이미지
주현도
지식공유자

안녕하세요 정훈님!

정확한 확인을 위해 블로그 페이지 캡쳐본과 Contentful에 작성한 코드 부분을 올려주실 수 있나요?

그리고 Contentful에서 코드를 작성하는 과정에서 코드 영역이 제대로 인식되지 않는 경우도 존재합니다.

따라서 명확하게 코드 영역을 다시 설정하신 후, pnpm clean && pnpm develop 명령어를 통해 캐시를 삭제하고 다시 로컬 서버를 실행해보시겠어요?

최정훈님의 프로필 이미지
최정훈
질문자

다시 했지만 해결되지 않고있습니다.

주현도님의 프로필 이미지
주현도
지식공유자

image.png

Contentful에서 위 사진과 같이 코드 영역을 등록하면 다른 일반 텍스트와 다른 폰트가 적용되는데, 정훈님께서 올려주신 사진은 그렇지 않아보입니다!

사진과 같이 코드 설정을 하신 후에 다시 로컬 서버를 실행해보시겠어요?