dynamic meta
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
"reacord": "workspace:*",
|
"reacord": "workspace:*",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
"react-head": "^3.4.0",
|
||||||
"react-router": "^6.2.1",
|
"react-router": "^6.2.1",
|
||||||
"react-router-dom": "^6.2.1"
|
"react-router-dom": "^6.2.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
|
import { description } from "reacord/package.json"
|
||||||
|
import { Meta, Title } from "react-head"
|
||||||
import { Route, Routes } from "react-router"
|
import { Route, Routes } from "react-router"
|
||||||
import { Link } from "react-router-dom"
|
import { Link } from "react-router-dom"
|
||||||
import { DocumentPage } from "./document-page"
|
import { DocumentPage } from "./document-page"
|
||||||
import { LandingPage } from "./landing-page"
|
import { LandingPage } from "./landing-page"
|
||||||
|
|
||||||
export function AppRoutes() {
|
export function App() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Title>Reacord</Title>
|
||||||
|
<Meta name="description" content={description} />
|
||||||
<nav>
|
<nav>
|
||||||
<Link to="/">Home</Link>
|
<Link to="/">Home</Link>{" "}
|
||||||
<Link to="docs/getting-started">Getting Started</Link>
|
<Link to="docs/getting-started">Getting Started</Link>{" "}
|
||||||
<Link to="docs/api">API Reference</Link>
|
<Link to="docs/api">API Reference</Link>
|
||||||
</nav>
|
</nav>
|
||||||
<Routes>
|
<Routes>
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import { hydrate } from "react-dom"
|
import { hydrate } from "react-dom"
|
||||||
|
import { HeadProvider } from "react-head"
|
||||||
import { BrowserRouter } from "react-router-dom"
|
import { BrowserRouter } from "react-router-dom"
|
||||||
import { Root } from "./root"
|
import { App } from "./app"
|
||||||
import { AppRoutes } from "./routes"
|
|
||||||
|
|
||||||
hydrate(
|
hydrate(
|
||||||
<Root>
|
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<AppRoutes />
|
<HeadProvider>
|
||||||
</BrowserRouter>
|
<App />
|
||||||
</Root>,
|
</HeadProvider>
|
||||||
document,
|
</BrowserRouter>,
|
||||||
|
document.body,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,13 +1,26 @@
|
|||||||
|
import { renderToString } from "react-dom/server"
|
||||||
|
import { HeadProvider } from "react-head"
|
||||||
import { StaticRouter } from "react-router-dom/server"
|
import { StaticRouter } from "react-router-dom/server"
|
||||||
import { Root } from "./root"
|
import { App } from "./app"
|
||||||
import { AppRoutes } from "./routes"
|
|
||||||
|
|
||||||
export async function render(url: string) {
|
export async function render(url: string) {
|
||||||
return (
|
const headTags: React.ReactElement[] = []
|
||||||
<Root>
|
|
||||||
|
const app = renderToString(
|
||||||
<StaticRouter location={url}>
|
<StaticRouter location={url}>
|
||||||
<AppRoutes />
|
<HeadProvider headTags={headTags}>
|
||||||
</StaticRouter>
|
<App />
|
||||||
</Root>
|
</HeadProvider>
|
||||||
|
</StaticRouter>,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return /* HTML */ `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
${renderToString(<>{headTags}</>)}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
${app}
|
||||||
|
</body>
|
||||||
|
`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
export function Root({ children }: { children: React.ReactNode }) {
|
|
||||||
return (
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charSet="UTF-8" />
|
|
||||||
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<meta name="description" content="test description" />
|
|
||||||
<title>Reacord</title>
|
|
||||||
<script
|
|
||||||
type="module"
|
|
||||||
src={
|
|
||||||
import.meta.env.PROD ? "/entry.client.js" : "/src/entry.client.tsx"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</head>
|
|
||||||
<body>{children}</body>
|
|
||||||
</html>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import compression from "compression"
|
import compression from "compression"
|
||||||
import express, { Router } from "express"
|
import express, { Router } from "express"
|
||||||
import { resolve } from "node:path"
|
import { resolve } from "node:path"
|
||||||
import { renderToString } from "react-dom/server"
|
|
||||||
import { createServer as createViteServer } from "vite"
|
import { createServer as createViteServer } from "vite"
|
||||||
import type * as entryModule from "./entry.server"
|
import type * as entryModule from "./entry.server"
|
||||||
|
|
||||||
@@ -20,10 +19,7 @@ async function createDevelopmentRouter() {
|
|||||||
"/src/entry.server.tsx",
|
"/src/entry.server.tsx",
|
||||||
)) as typeof entryModule
|
)) as typeof entryModule
|
||||||
|
|
||||||
const html = await vite.transformIndexHtml(
|
const html = await vite.transformIndexHtml(url, await render(url))
|
||||||
url,
|
|
||||||
renderToString(await render(url)),
|
|
||||||
)
|
|
||||||
|
|
||||||
res.status(200).set({ "Content-Type": "text/html" }).end(html)
|
res.status(200).set({ "Content-Type": "text/html" }).end(html)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -47,7 +43,7 @@ function createProductionRouter() {
|
|||||||
res
|
res
|
||||||
.status(200)
|
.status(200)
|
||||||
.set({ "Content-Type": "text/html" })
|
.set({ "Content-Type": "text/html" })
|
||||||
.end(renderToString(await render(req.originalUrl)))
|
.end(await render(req.originalUrl))
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
res.status(500).end(error.stack || error.message)
|
res.status(500).end(error.stack || error.message)
|
||||||
|
|||||||
13
pnpm-lock.yaml
generated
13
pnpm-lock.yaml
generated
@@ -124,6 +124,7 @@ importers:
|
|||||||
reacord: workspace:*
|
reacord: workspace:*
|
||||||
react: ^17.0.2
|
react: ^17.0.2
|
||||||
react-dom: ^17.0.2
|
react-dom: ^17.0.2
|
||||||
|
react-head: ^3.4.0
|
||||||
react-router: ^6.2.1
|
react-router: ^6.2.1
|
||||||
react-router-dom: ^6.2.1
|
react-router-dom: ^6.2.1
|
||||||
typescript: ^4.5.4
|
typescript: ^4.5.4
|
||||||
@@ -133,6 +134,7 @@ importers:
|
|||||||
reacord: link:../reacord
|
reacord: link:../reacord
|
||||||
react: 17.0.2
|
react: 17.0.2
|
||||||
react-dom: 17.0.2_react@17.0.2
|
react-dom: 17.0.2_react@17.0.2
|
||||||
|
react-head: 3.4.0_react-dom@17.0.2+react@17.0.2
|
||||||
react-router: 6.2.1_react@17.0.2
|
react-router: 6.2.1_react@17.0.2
|
||||||
react-router-dom: 6.2.1_react-dom@17.0.2+react@17.0.2
|
react-router-dom: 6.2.1_react-dom@17.0.2+react@17.0.2
|
||||||
devDependencies:
|
devDependencies:
|
||||||
@@ -7489,6 +7491,17 @@ packages:
|
|||||||
use-sidecar: 1.0.5_react@17.0.2
|
use-sidecar: 1.0.5_react@17.0.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/react-head/3.4.0_react-dom@17.0.2+react@17.0.2:
|
||||||
|
resolution: {integrity: sha512-T+a+WTN2lQECle3KdUBTnXMpjzOTDRFS1f2jCLP9H64XBXgayxadoLkzWSiJD793zE8IMWzQ8xKe3V573es9NQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.3'
|
||||||
|
react-dom: '>=16.3'
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.16.5
|
||||||
|
react: 17.0.2
|
||||||
|
react-dom: 17.0.2_react@17.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-is/16.13.1:
|
/react-is/16.13.1:
|
||||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user