|
1 | 1 | import { renderToString } from "react-dom/server"; |
2 | | -import { App } from "./App"; |
3 | | -import { createProductStore, initialProductState } from "./entities"; |
4 | | -import { ProductProvider } from "./entities/products/context/ProductContext"; |
5 | 2 | import { RouterProvider } from "./entities/products/context/RouterContext"; |
6 | | -import { HomePage, ProductDetailPage, NotFoundPage } from "./pages"; |
| 3 | +import { HomePage, NotFoundPage, ProductDetailPage } from "./pages"; |
7 | 4 | import { UniversalRouter } from "./router/UniversalRouter"; |
8 | 5 | import type { PageWithServer } from "./utils/withServerSideProps"; |
9 | 6 | import type { StringRecord } from "@hanghae-plus/lib"; |
| 7 | +import { withProviders } from "./pages/withProviders.tsx"; |
| 8 | +import type { PropsWithChildren } from "react"; |
10 | 9 |
|
11 | 10 | type RenderResult = { |
12 | 11 | head: string; |
13 | 12 | html: string; |
14 | 13 | __INITIAL_DATA__: Record<string, unknown>; |
15 | 14 | }; |
16 | 15 |
|
17 | | -export const render = async (pathname: string, query: StringRecord): Promise<RenderResult> => { |
18 | | - const renderApp = () => { |
19 | | - return ( |
20 | | - <RouterProvider router={router}> |
21 | | - <ProductProvider productStore={createProductStore(initialProductState)}> |
22 | | - <App /> |
23 | | - </ProductProvider> |
24 | | - </RouterProvider> |
25 | | - ); |
26 | | - }; |
| 16 | +type ServerParams = Parameters<NonNullable<PageWithServer["ssr"]>>[0]; |
27 | 17 |
|
| 18 | +export const render = async (pathname: string, query: StringRecord): Promise<RenderResult> => { |
28 | 19 | const router = new UniversalRouter<PageWithServer>(); |
29 | 20 |
|
30 | | - router.addRoute("/", HomePage); |
| 21 | + const App = ({ children }: PropsWithChildren) => { |
| 22 | + return <RouterProvider router={router}>{children}</RouterProvider>; |
| 23 | + }; |
31 | 24 |
|
32 | | - router.addRoute("/product/:id/", ProductDetailPage); |
33 | | - router.addRoute(".*", NotFoundPage); |
| 25 | + router.addRoute("/", Object.assign(withProviders(HomePage), { ...HomePage })); |
| 26 | + router.addRoute("/product/:id/", Object.assign(withProviders(ProductDetailPage), { ...ProductDetailPage })); |
| 27 | + router.addRoute(".*", Object.assign(withProviders(NotFoundPage), { ...NotFoundPage })); |
34 | 28 |
|
35 | 29 | router.start(pathname); |
36 | 30 |
|
37 | | - type ServerParams = Parameters<NonNullable<PageWithServer["ssr"]>>[0]; |
38 | | - const serverParams: ServerParams = { query, params: router.params } as ServerParams; |
39 | | - |
40 | | - if (router.target?.ssr) { |
41 | | - const result = await router.target.ssr(serverParams); |
42 | | - const title = (result as unknown as { metadata?: { title?: string } })?.metadata?.title ?? ""; |
43 | | - const html = renderToString(renderApp()) ?? ""; |
44 | | - const data = (result as unknown as { data?: Record<string, unknown> })?.data ?? {}; |
| 31 | + const serverParams = { query, params: router.params } as ServerParams; |
45 | 32 |
|
46 | | - return { |
47 | | - head: `<title>${title}</title>`, |
48 | | - html, |
49 | | - __INITIAL_DATA__: data, |
50 | | - }; |
51 | | - } |
| 33 | + const PageComponent = router.target!; |
| 34 | + const result = await PageComponent.ssr?.(serverParams); |
| 35 | + const metadata = await PageComponent.metadata?.(serverParams); |
| 36 | + const html = renderToString( |
| 37 | + <App> |
| 38 | + <PageComponent productState={result} /> |
| 39 | + </App>, |
| 40 | + ); |
52 | 41 |
|
53 | | - const metadata = await router.target?.metadata?.(serverParams); |
54 | 42 | return { |
55 | 43 | head: `<title>${metadata?.title ?? ""}</title>`, |
56 | | - html: "", |
57 | | - __INITIAL_DATA__: {}, |
| 44 | + html, |
| 45 | + __INITIAL_DATA__: (result ?? {}) as Record<string, unknown>, |
58 | 46 | }; |
59 | 47 | }; |
0 commit comments