繁体   English   中英

Next.js 在 html 标记中呈现应用程序作为字符串

[英]Next.js render app inside html markup coming as string

我需要在第三方 html 标记中构建我的 Next.js 应用程序。

标记如下:

头文件.txt

 <html> <head> <title>Some title</title> </head> <body> <header>Some header</header> <div>

页脚.txt

 </div> <footer>Some footer</footer> </body> </html>

这些文件是动态生成到一个文件夹中的。 当我呈现我的 next.js 应用程序时,我需要将它们包裹在我的应用程序周围。

我使用名为的包创建了一个工作示例:html-react-parser

我从 _document.js 中的文件解析标记,我正在寻找一个自定义元素 ID,我将用下一个 js 应用程序替换它,如下所示:

 const header = fs.readFileSync(path.resolve(ROOT + '/resources', 'header.txt'), 'utf8'); const footer = fs.readFileSync(path.resolve(ROOT + '/resources', 'footer.txt'), 'utf8'); const shell = ` ${header} <main id="react-app"></main> ${footer} `; // later in the render method od _document.js: render() { return ( <React.Fragment> {parse(shell, { replace: domNode => { if (domNode.attribs && domNode.attribs.id === 'react-app') { return ( <React.Fragment> <Main/> <NextScript/> </React.Fragment> ) } } })} </React.Fragment> ) }

虽然这有效,但我的问题是,这不是 html-react-parser 的目的,因为它将文件的标记转换为 react 组件,并在转换过程中抛出许多关于错误使用的 html props 的警告,react 无法使用.

也许解决方案是使用危险的SetInnerHTML,但在这种情况下,我不能注入和。

 // it fails because it wont treat the components as normal html // <Main/><NextScript/> are not evaluated const header = fs.readFileSync(path.resolve(ROOT + '/resources', 'header.txt'), 'utf8'); const footer = fs.readFileSync(path.resolve(ROOT + '/resources', 'footer.txt'), 'utf8'); const shell = ` ${header} <React.Fragment> <Main/> <NextScript/> </React.Fragment> ${footer} `; // later in the render method od _document.js: render(<html dangerouslySetInnerHTML={{__html: shell}}/>)

如果有人有一个想法,我如何设法将我的下一个应用程序围绕来自文件的标记包装起来,请给我一些建议。

您可以使用自定义服务器实现这一点,

const express = require('express')
const next = require('next')

const header = fs.readFileSync(path.resolve(ROOT + '/resources', 'header.txt'), 'utf8');
const footer = fs.readFileSync(path.resolve(ROOT + '/resources', 'footer.txt'), 'utf8');

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const server = express()

  server.all('*', async (req, res) => {
    const nextResponse = await handle(req, res);
    return mergeHTML(header, footer, nextResponse); // You will need to "merge" cause nextResponse has `head` & `body` as well.
  })

  server.listen(port, err => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })
})

mergeHTML应该从你的header & next 的 head & body 合并 head 。 你可以使用cheerio来帮助你。

我使用dangerouslySetInnerHTML 解决了这个问题。 基本上它不关心你传递给它的字符串语法,所以我在 _document.js 中提出了以下解决方案:

 <Html> <html dangerouslySetInnerHTML={{__html: header}}/> <Head /> <body> <Main /> <NextScript /> </body> <html dangerouslySetInnerHTML={{__html: footer}}/> </Html>

两个危险的SetInnerHTML 调用都使用奇数个元素并环绕next.js 组件。

如果有人有另一个解决方案可能没有危险地SetInnerHTML 请评论它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM