简体   繁体   English

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

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

I need to build my Next.js app inside a third-party html markup.我需要在第三方 html 标记中构建我的 Next.js 应用程序。

The markup is given as follows:标记如下:

header.txt头文件.txt

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

footer.txt页脚.txt

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

This files are dynamically generated into a folder.这些文件是动态生成到一个文件夹中的。 When I render my next.js application, I need to wrap them around my application.当我呈现我的 next.js 应用程序时,我需要将它们包裹在我的应用程序周围。

I created a working example using the package called: html-react-parser我使用名为的包创建了一个工作示例:html-react-parser

I parse the markup from the files in the _document.js and I am looking for a custom element id which I am replacing with the next js app as follows:我从 _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> ) }

Although this works, my problem is, that this is not the purpose of the html-react-parser because it converts the markup of the files to react components, and throws many warnings during the conversion about wrongly used html props which react can not use.虽然这有效,但我的问题是,这不是 html-react-parser 的目的,因为它将文件的标记转换为 react 组件,并在转换过程中抛出许多关于错误使用的 html props 的警告,react 无法使用.

Maybe the solution would be to use dangerouslySetInnerHTML, but in this case I can not inject and .也许解决方案是使用危险的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}}/>)

If anybody has an Idea how could I manage to wrap my next app around my markup coming from the files, please give me some advice.如果有人有一个想法,我如何设法将我的下一个应用程序围绕来自文件的标记包装起来,请给我一些建议。

You can achieve that with custom server ,您可以使用自定义服务器实现这一点,

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 should merge head from your header & next's head & the body. mergeHTML应该从你的header & next 的 head & body 合并 head 。 You can use cheerio to help you with that.你可以使用cheerio来帮助你。

I solved the problem using dangerouslySetInnerHTML.我使用dangerouslySetInnerHTML 解决了这个问题。 Basically It does not care about the string syntax you pass into it, so I came up with the following solution in _document.js:基本上它不关心你传递给它的字符串语法,所以我在 _document.js 中提出了以下解决方案:

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

Both calls of dangerouslySetInnerHTML are taking the odd number of elements and wrapping around the next.js components.两个危险的SetInnerHTML 调用都使用奇数个元素并环绕next.js 组件。

By the was if anybody has an another solution maybe without dangerouslySetInnerHTML please comment it.如果有人有另一个解决方案可能没有危险地SetInnerHTML 请评论它。

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

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