Next.JS - Gist, встроенный в уценку, отображаемую с помощью опасноSetInnerHTML, отображается только после полной загрузки страницы, а не загрузки маршрута React

У меня есть серия сообщений в блогах, хранящихся в файлах MD, некоторые из них содержат несколько встраиваний Gist в виде тегов скриптов.

Содержимое MD отображается на страницу с помощью dangerousSetInnerHTML, и все в порядке, если перейти к странице напрямую. Однако, когда используется маршрутизация приложения и полное обновление страницы не происходит, тег скрипта включается в разметку, но не выполняется.

В следующем примере используется пример блога Next.JS по умолчанию: https://github.com/vercel/next-learn-starter/tree/master/basics-final.

Уценка:

      ---
title: "Example of GIST embedding"
date: "2020-02-20"
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut id arcu at arcu pretium porta. Nam feugiat est ut lectus imperdiet venenatis. Ut tempus vitae lectus id vestibulum. Sed tristique est metus. Ut pretium malesuada risus. Maecenas eget diam tristique, sagittis velit ac, efficitur nisi. Quisque lectus lorem, vehicula at mi vitae, dapibus volutpat augue. Sed dignissim pharetra ligula a efficitur. In ultrices imperdiet libero. Quisque ornare erat eu elit ullamcorper faucibus. Maecenas mattis sem a mauris posuere iaculis.

<script src="https://gist.github.com/robearlam/aec15c65aaffbd5ec00a826c5cbe57ad.js"></script>

Etiam sed interdum ligula, nec tincidunt justo. Aliquam erat volutpat. Fusce in scelerisque nisl. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin venenatis lectus at ligula mollis dapibus. Praesent condimentum metus fringilla, commodo enim non, fringilla dui. Vivamus nec ligula lacinia ante semper rhoncus eu sed nisi. In ac dolor vel lorem tincidunt lacinia. Praesent quis mattis mi, at finibus velit. Etiam auctor, magna fermentum tincidunt interdum, nulla augue porttitor enim, ac lobortis felis eros id dui. Suspendisse dignissim, dui sit amet pulvinar iaculis, nisi tellus rhoncus dolor, eu gravida risus massa accumsan magna.

Страница

      import Layout from '../../components/layout'
import { getAllPostIds, getPostData } from '../../lib/posts'
import Head from 'next/head'
import Date from '../../components/date'
import utilStyles from '../../styles/utils.module.css'

export default function Post({ postData }) {
  return (
    <Layout>
      <Head>
        <title>{postData.title}</title>
      </Head>
      <article>
        <h1 className={utilStyles.headingXl}>{postData.title}</h1>
        <div className={utilStyles.lightText}>
          <Date dateString={postData.date} />
        </div>
        <div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
      </article>
    </Layout>
  )
}

export async function getStaticPaths() {
  const paths = getAllPostIds()
  return {
    paths,
    fallback: false
  }
}

export async function getStaticProps({ params }) {
  const postData = await getPostData(params.id)
  return {
    props: {
      postData
    }
  }
}

Функция Lib

      export async function getPostData(id) {
  const fullPath = path.join(postsDirectory, `${id}.md`)
  const fileContents = fs.readFileSync(fullPath, 'utf8')

  // Use gray-matter to parse the post metadata section
  const matterResult = matter(fileContents)

  // Use remark to convert markdown into HTML string
  const processedContent = await remark()
    .use(html)
    .process(matterResult.content)
  const contentHtml = processedContent.toString()

  // Combine the data with the id and contentHtml
  return {
    id,
    contentHtml,
    ...matterResult.data
  }

У меня также есть репо, показывающее проблему здесь: https://github.com/robearlam/gist-embedding-issue

Ваше здоровье!

1 ответ

Я столкнулся с той же проблемой, я нашел этот пост очень полезным .

По сути, вы создаете собственный блок кода, который форматирует ваши теги кода в строке.

Это вы используете <ReactMarkdown>компонент для отображения вашей уценки (вместо примечания), а затем вы используете библиотеку react-syntax-highlighter в своем пользовательском компоненте блока кода.

При рендеринге уценки используйте:

      import CodeBlock from "../../components/codeblock"

<ReactMarkdown components={CodeBlock}>{your markdown data here}</ReactMarkdown>

Импорт вашего пользовательского компонента кодового блока для процессора уценки.

Пример пользовательского блока кода Тома ниже:

      // components/codeblock.js
import React from "react"
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
import {dracula} from 'react-syntax-highlighter/dist/cjs/styles/prism';

const CodeBlock = {
  code({node, inline, className, children, ...props}) {
    const match = /language-(\w+)/.exec(className || '')
    return !inline && match ? (
    <SyntaxHighlighter 
      style={dracula} 
      language={match[1]} 
      PreTag="div" {...props}>
      {String(children).replace(/\n$/, '')}
    </SyntaxHighlighter>

    ) : (
      <code className={className} {...props}>
        {children}
      </code>
    )
  }
}

export default CodeBlock
Другие вопросы по тегам