import * as React from 'react'
import * as fs from 'fs'
import * as cheerio from 'cheerio'
import * as types from 'src/types'
import { IncomingMessage, ServerResponse } from 'http'
import { getConfig } from 'config/config'
import { findMatchedRoute, callGetInitialProps } from 'src/utils'
import ReactDOMServer from 'react-dom/server'
import Root from 'src/Root'
import DefaultApp from 'src/App'
const config = getConfig()
const htmlPath = config.isDev ? config.htmlTemplatePath : config.builtHTMLPath
const template = fs.readFileSync(htmlPath, 'utf8')
function writeDataToHTML($: CheerioStatic, pageProps: object) {
const data = JSON.stringify({
pageProps,
})
const scripts = $('script')
if (scripts.length) {
$(scripts.get(0)).before(`
`
)
} else {
$('body').append(
``
)
}
}
function appendScriptOnDevelop($: CheerioStatic) {
if (config.isDev) {
const scriptUrl = config.publicPath + 'app.js'
$('body').append(`
`)
}
}
export async function renderToString(
req: IncomingMessage,
res: ServerResponse,
url: string,
options: types.RenderOptions,
): Promise {
const $ = cheerio.load(template, {
decodeEntities: config.decodeEntities,
})
const matched = findMatchedRoute(url, options.routes)
const App = options.App || DefaultApp
const initialProps = await callGetInitialProps(
App,
matched ? matched.component : null,
url,
req,
res,
)
const content = ReactDOMServer.renderToString(
)
$(options.container).html(content)
appendScriptOnDevelop($)
writeDataToHTML($, initialProps)
return $.html()
}