Taron Mehrabyan
Taron Mehrabyan

Reputation: 2229

Accessing cookies from React SSR

Here is the simple thing. React routing redirect path depends on the value in cookies, so how do I handle it Server Side?

render() {
  something = cookie.get('my-something-value') || 'default '; // always takes defualt value beacuse cookies are not available 
  return (
    <Switch>
      <Route />
      <Route />
      <Redirect to={`/something/${val}`}/>
    </Switch>
  )
}

So renderToString method in the server parses elements to string ignoring this condition and I get wrong redirect even though I have cookies set

Upvotes: 4

Views: 11706

Answers (2)

Asanka
Asanka

Reputation: 618

use cookie parser middleware

npm i cookie-parser

Example

var express = require('express')
var cookieParser = require('cookie-parser')

var app = express()
app.use(cookieParser())

app.get('/', function (req, res) {
  // Cookies that have not been signed
  console.log('Cookies: ', req.cookies)

  // Cookies that have been signed
  console.log('Signed Cookies: ', req.signedCookies)
})

app.listen(8080)

Upvotes: 0

Sunil Chaudhary
Sunil Chaudhary

Reputation: 4743

I had faced similar kind of issue. It was resolved by:

  • Pass an extra prop (here: serverCookie) containing cookie to your routes in renderToString.
  • In the render method (where you have defined all routes/redirect); check if it is getting called on client or server. If it is on server-side, use the new prop (here: serverCookie) containing cookie otherwise use the cookie.get from client-side.
  • The extra prop (here: serverCookie) is not available when routes are rendered in client-side.

My renderToString on server side looked somewhat like this:

renderToString(
  <Provider store={store}>
    <StaticRouter ...>
      <MyRoutes ... serverCookie={req.headers.cookie} />
    </StaticRouter>
  </Provider>
)

MyRoutes file looked like:

render(){
  const cookie = isServerSide
    ? this.props.serverCookie
    : cookie.get('my-something-value')
  const path = cookie ? "/pathC" : "/pathD"
  return (
    <Switch>
        <Route
          path="/pathA"
          component={ComponentA}
        />
        <Route
          path="/pathB"
          component={ComponentA}
        />
        <Redirect to={path} />
      ...
    </Switch>
  )
}

Note: You will need to parse your cookies properly using some cookie-parser before using.

Hope it helps and solves your issue. Revert for any doubts/clarifications.

Upvotes: 3

Related Questions