Skip to content

Commit

Permalink
feat: react-cookie (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
denchiklut authored Sep 29, 2024
1 parent c9bbe6a commit c6caa3d
Show file tree
Hide file tree
Showing 14 changed files with 113 additions and 29 deletions.
27 changes: 13 additions & 14 deletions @types/app/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
/**
* If you have `imports/exports` statements
* You need put `Window` & `Express` declarations into `declare global {}`
* @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html
*/
import type Cookies from "universal-cookie"

interface Window {
nonce: string
}

namespace Express {
interface Response {
renderApp(): Promise<void>
declare global {
interface Window {
nonce: string
}

interface Request {
nonce: string
namespace Express {
interface Response {
renderApp(): Promise<void>
}

interface Request {
nonce: string
universalCookies: Cookies
}
}
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@
"morgan": "^1.10.0",
"postcss": "^8.4.47",
"react": "^18.3.1",
"react-cookie": "^7.2.0",
"react-dom": "^18.3.1",
"react-helmet-async": "^2.0.5",
"react-router": "^6.26.2",
"react-router-dom": "^6.26.2",
"reflect-metadata": "^0.2.2",
"universal-cookie-express": "^7.2.0",
"url-join": "^5.0.0",
"uuid": "^10.0.0",
"winston": "^3.14.2",
Expand Down
9 changes: 6 additions & 3 deletions src/client/components/@shared/app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { type FC, StrictMode } from 'react'
import { getENV, type AppProps } from 'src/common'
import { CookiesProvider } from 'react-cookie'
import { HelmetProvider } from 'react-helmet-async'
import { getENV, type AppProps } from 'src/common'

export const App: FC<AppProps> = ({ children, nonce, helmetContext }) => {
export const App: FC<AppProps> = ({ children, nonce, cookies, helmetContext }) => {
__webpack_nonce__ = nonce
__webpack_public_path__ = getENV('CLIENT_PUBLIC_PATH')

return (
<StrictMode>
<HelmetProvider context={helmetContext}>{children}</HelmetProvider>
<HelmetProvider context={helmetContext}>
<CookiesProvider cookies={cookies}>{children}</CookiesProvider>
</HelmetProvider>
</StrictMode>
)
}
21 changes: 21 additions & 0 deletions src/client/components/home/cookie-demo/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useCookies } from 'react-cookie'
import css from './styles.scss'

export const CookieDemo = () => {
const [cookies, setCookie] = useCookies()

return (
<div className={css.wrapper}>
<b>Cookie demo</b>

<button onClick={() => setCookie('hide', !cookies.hide)}>Toggle</button>
{!cookies.hide && (
<p>
Reload the page!
<br />
There will be no hydration errors since its sync between client/server
</p>
)}
</div>
)
}
4 changes: 4 additions & 0 deletions src/client/components/home/cookie-demo/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.wrapper {
display: grid;
justify-items: start;
}
5 changes: 4 additions & 1 deletion src/client/components/home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Suspense } from 'react'
import { logger, getENV } from 'src/common'
import { CookieDemo } from './cookie-demo'
import { Posts } from './posts'
import { State } from './state'
import css from './styles.scss'
Expand All @@ -12,7 +13,9 @@ export const Home = () => {
<div className={css.wrapper}>
<h3>Home page!</h3>
<State />

<hr />
<CookieDemo />
<hr />
<Suspense fallback={<p>fetching posts...</p>}>
<Posts />
</Suspense>
Expand Down
13 changes: 8 additions & 5 deletions src/client/components/home/posts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ export const Posts = () => {
const posts = useLoaderData() as PostsResponse

return (
<ul>
{posts.map(post => (
<li key={post.id}>{post.text}</li>
))}
</ul>
<div>
<b>Data fetching demo</b>
<ul>
{posts.map(post => (
<li key={post.id}>{post.text}</li>
))}
</ul>
</div>
)
}
9 changes: 7 additions & 2 deletions src/client/components/home/state/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ export const State = () => {
const [count, setCount] = useState(0)

return (
<>
<div>
<b>HMR Demo</b>
<p>
Click Increase button and update the code. You selected state will be preserved with
HMR update.
</p>
<p>count {count}</p>
<button onClick={() => setCount(count + 1)}>Increase</button>
</>
</div>
)
}
2 changes: 2 additions & 0 deletions src/common/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { ReactNode } from 'react'
import type { HelmetServerState } from 'react-helmet-async'
import type Cookies from 'universal-cookie'

export interface AppProps {
nonce: string
cookies?: Cookies
children: ReactNode
helmetContext?: { helmet?: HelmetServerState }
}
3 changes: 2 additions & 1 deletion src/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import express from 'express'
import { favicon, hmr, render, logger, error, uuid } from 'server/middleware'
import { favicon, hmr, render, logger, cookieParser, uuid, error } from 'server/middleware'
import { bootstrap } from 'server/utils'
import { router } from 'server/router'

export const app = express()
.use(cookieParser)
.use(favicon())
.use(uuid)
.use(logger)
Expand Down
3 changes: 3 additions & 0 deletions src/server/middleware/cookie/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import cookieParserMiddleware from 'universal-cookie-express'

export const cookieParser = cookieParserMiddleware()
1 change: 1 addition & 0 deletions src/server/middleware/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export * from './hmr'
export * from './error'
export * from './render'
export * from './favicon'
export * from './cookie'
export * from './logger'
export * from './uuid'
export * from './pwa'
2 changes: 1 addition & 1 deletion src/server/middleware/render/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const render = (req: Request, res: Response, next: NextFunction) => {
context.basename = basename

const jsx = chunkExtractor.collectChunks(
<App nonce={nonce} helmetContext={helmetContext}>
<App nonce={nonce} cookies={req.universalCookies} helmetContext={helmetContext}>
<StaticRouterProvider
router={createStaticRouter(routes, context)}
context={context}
Expand Down
41 changes: 39 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1970,6 +1970,11 @@
dependencies:
"@types/node" "*"

"@types/cookie@^0.6.0":
version "0.6.0"
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5"
integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==

"@types/[email protected]":
version "0.0.39"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
Expand Down Expand Up @@ -2032,6 +2037,14 @@
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==

"@types/hoist-non-react-statics@^3.3.5":
version "3.3.5"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494"
integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"

"@types/html-minifier-terser@^6.0.0":
version "6.1.0"
resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35"
Expand Down Expand Up @@ -3542,7 +3555,7 @@ cookie-signature@^1.2.1:
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.2.1.tgz#790dea2cce64638c7ae04d9fabed193bd7ccf3b4"
integrity sha512-78KWk9T26NhzXtuL26cIJ8/qNHANyJ/ZYrmEXFzUmhZdjpBv+DlWlOANRTGBt48YcyslsLrj0bMLFTmXvLRCOw==

[email protected]:
[email protected], cookie@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
Expand Down Expand Up @@ -5244,7 +5257,7 @@ hermes-parser@^0.20.1:
dependencies:
hermes-estree "0.20.1"

hoist-non-react-statics@^3.3.1:
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
Expand Down Expand Up @@ -7931,6 +7944,15 @@ raw-body@^3.0.0:
iconv-lite "0.6.3"
unpipe "1.0.0"

react-cookie@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/react-cookie/-/react-cookie-7.2.0.tgz#5770cd8d6b3c60c5d34ec4b7926f90281aee22ae"
integrity sha512-mqhPERUyfOljq5yJ4woDFI33bjEtigsl8JDJdPPeNhr0eSVZmBc/2Vdf8mFxOUktQxhxTR1T+uF0/FRTZyBEgw==
dependencies:
"@types/hoist-non-react-statics" "^3.3.5"
hoist-non-react-statics "^3.3.2"
universal-cookie "^7.0.0"

react-dom@^18.3.1:
version "18.3.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4"
Expand Down Expand Up @@ -9505,6 +9527,21 @@ unique-string@^2.0.0:
dependencies:
crypto-random-string "^2.0.0"

universal-cookie-express@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/universal-cookie-express/-/universal-cookie-express-7.2.0.tgz#e512e2a5db8624b9330056324ad166bdb472c1fd"
integrity sha512-JC8ADzPexzv1xZhCOvRPWHeKCCYsoEUxS3f2dJV4kRXZMCss5VQ0DWKAeoONg+P3OOoee0NMqcOIkvRaNWagUw==
dependencies:
universal-cookie "^7.0.0"

universal-cookie@^7.0.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/universal-cookie/-/universal-cookie-7.2.0.tgz#1f3fa9c575d863ac41b4e42272d240ae2d32c047"
integrity sha512-PvcyflJAYACJKr28HABxkGemML5vafHmiL4ICe3e+BEKXRMt0GaFLZhAwgv637kFFnnfiSJ8e6jknrKkMrU+PQ==
dependencies:
"@types/cookie" "^0.6.0"
cookie "^0.6.0"

universalify@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0"
Expand Down

0 comments on commit c6caa3d

Please sign in to comment.