Skip to content

Commit 274ac85

Browse files
author
Romuald Brillout
committed
boilerplate Vite w/ vite-plugin-ssr
0 parents  commit 274ac85

19 files changed

+463
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
dist/

package.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"scripts": {
3+
"dev": "npm run server",
4+
"prod": "npm run build && npm run server:prod",
5+
"build": "vite build",
6+
"server": "ts-node ./server/index.ts",
7+
"server:prod": "cross-env NODE_ENV=production ts-node ./server/index.ts"
8+
},
9+
"dependencies": {
10+
"@types/compression": "^1.7.2",
11+
"@types/express": "^4.17.14",
12+
"@types/node": "^18.11.9",
13+
"@types/react": "^18.0.8",
14+
"@types/react-dom": "^18.0.3",
15+
"@vitejs/plugin-react": "^3.0.0",
16+
"compression": "^1.7.4",
17+
"cross-env": "^7.0.3",
18+
"express": "^4.18.1",
19+
"react": "^18.2.0",
20+
"react-dom": "^18.2.0",
21+
"sirv": "^2.0.2",
22+
"ts-node": "^10.9.1",
23+
"typescript": "^4.9.4",
24+
"vite": "^4.0.3",
25+
"vite-plugin-ssr": "^0.4.112"
26+
},
27+
"type": "module"
28+
}

pages/about/code.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
code {
2+
font-family: monospace;
3+
background-color: #eaeaea;
4+
padding: 3px 5px;
5+
border-radius: 4px;
6+
}

pages/about/index.page.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react'
2+
import './code.css'
3+
4+
export { Page }
5+
6+
function Page() {
7+
return (
8+
<>
9+
<h1>About</h1>
10+
<p>
11+
Example of using <code>vite-plugin-ssr</code>.
12+
</p>
13+
</>
14+
)
15+
}

pages/index/Counter.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React, { useState } from 'react'
2+
3+
export { Counter }
4+
5+
function Counter() {
6+
const [count, setCount] = useState(0)
7+
return (
8+
<button type="button" onClick={() => setCount((count) => count + 1)}>
9+
Counter {count}
10+
</button>
11+
)
12+
}

pages/index/index.page.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react'
2+
import { Counter } from './Counter'
3+
4+
export { Page }
5+
6+
function Page() {
7+
return (
8+
<>
9+
<h1>Welcome</h1>
10+
This page is:
11+
<ul>
12+
<li>Rendered to HTML.</li>
13+
<li>
14+
Interactive. <Counter />
15+
</li>
16+
</ul>
17+
</>
18+
)
19+
}

renderer/Link.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from 'react'
2+
import { usePageContext } from './usePageContext'
3+
4+
export { Link }
5+
6+
function Link(props: { href?: string; className?: string; children: React.ReactNode }) {
7+
const pageContext = usePageContext()
8+
const className = [props.className, pageContext.urlPathname === props.href && 'is-active'].filter(Boolean).join(' ')
9+
return <a {...props} className={className} />
10+
}

renderer/PageShell.css

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* This CSS is common to all pages */
2+
3+
body {
4+
margin: 0;
5+
font-family: sans-serif;
6+
}
7+
* {
8+
box-sizing: border-box;
9+
}
10+
a {
11+
text-decoration: none;
12+
}
13+
14+
.navitem {
15+
padding: 3px 10px;
16+
}
17+
.navitem.is-active {
18+
background-color: #eee;
19+
}

renderer/PageShell.tsx

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import React from 'react'
2+
import logo from './logo.svg'
3+
import { PageContextProvider } from './usePageContext'
4+
import type { PageContext } from './types'
5+
import './PageShell.css'
6+
import { Link } from './Link'
7+
8+
export { PageShell }
9+
10+
function PageShell({ children, pageContext }: { children: React.ReactNode; pageContext: PageContext }) {
11+
return (
12+
<React.StrictMode>
13+
<PageContextProvider pageContext={pageContext}>
14+
<Layout>
15+
<Sidebar>
16+
<Logo />
17+
<Link className="navitem" href="/">
18+
Home
19+
</Link>
20+
<Link className="navitem" href="/about">
21+
About
22+
</Link>
23+
</Sidebar>
24+
<Content>{children}</Content>
25+
</Layout>
26+
</PageContextProvider>
27+
</React.StrictMode>
28+
)
29+
}
30+
31+
function Layout({ children }: { children: React.ReactNode }) {
32+
return (
33+
<div
34+
style={{
35+
display: 'flex',
36+
maxWidth: 900,
37+
margin: 'auto'
38+
}}
39+
>
40+
{children}
41+
</div>
42+
)
43+
}
44+
45+
function Sidebar({ children }: { children: React.ReactNode }) {
46+
return (
47+
<div
48+
style={{
49+
padding: 20,
50+
flexShrink: 0,
51+
display: 'flex',
52+
flexDirection: 'column',
53+
alignItems: 'center',
54+
lineHeight: '1.8em'
55+
}}
56+
>
57+
{children}
58+
</div>
59+
)
60+
}
61+
62+
function Content({ children }: { children: React.ReactNode }) {
63+
return (
64+
<div
65+
style={{
66+
padding: 20,
67+
paddingBottom: 50,
68+
borderLeft: '2px solid #eee',
69+
minHeight: '100vh'
70+
}}
71+
>
72+
{children}
73+
</div>
74+
)
75+
}
76+
77+
function Logo() {
78+
return (
79+
<div
80+
style={{
81+
marginTop: 20,
82+
marginBottom: 10
83+
}}
84+
>
85+
<a href="/">
86+
<img src={logo} height={64} width={64} alt="logo" />
87+
</a>
88+
</div>
89+
)
90+
}

renderer/_default.page.client.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export { render }
2+
3+
import React from 'react'
4+
import { hydrateRoot } from 'react-dom/client'
5+
import { PageShell } from './PageShell'
6+
import type { PageContextClient } from './types'
7+
8+
// This render() hook only supports SSR, see https://vite-plugin-ssr.com/render-modes for how to modify render() to support SPA
9+
async function render(pageContext: PageContextClient) {
10+
const { Page, pageProps } = pageContext
11+
if (!Page) throw new Error('Client-side render() hook expects pageContext.Page to be defined')
12+
hydrateRoot(
13+
document.getElementById('page-view')!,
14+
<PageShell pageContext={pageContext}>
15+
<Page {...pageProps} />
16+
</PageShell>
17+
)
18+
}
19+
20+
/* To enable Client-side Routing:
21+
export const clientRouting = true
22+
// !! WARNING !! Before doing so, read https://vite-plugin-ssr.com/clientRouting */

0 commit comments

Comments
 (0)