npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

redux-observables-server-side-rendering

v0.1.3

Published

library to use redux observables in combination with ssr and react-router

Downloads

11

Readme

redux-observables-server-side-rendering

npm version travis build

A middleware that works in combination with react-router, react-router-redux and redux-observables.

Installation

npm install --save redux-observables-server-side-rendering

Usage

FIRST OF ALL
This is very customized to an existing project, but it works.
If you have suggestions to do this in a better or more common way don't, hesitate to make a pull request or message me.

Once you've configured your application you can use the ssr object created inside the server, handed over to the store and the epic middleware as dependency, in your own epic implementations.

// example epic
const myDataFetchingEpic = (action$, store, ssr) => actions$
  .ofType('SPECIFIC_ACTION_TYPE')
  .switchMap(action => {
    return ssr.observe(action, 
      getSomeDataFetchingObservable()
        .flatMap(response => [
          actionCreator1(response.data1),
          actionCreator2(response.data1),
        ])        
    )
  })

You can find below how to configure your application to get ssr with redux-observables work:

Configuration

Let's assume we have have redux application with components, containers, modules and redux-observables for data fetching. The app runs with react-router and react-router-redux and has a config folder:

// project folder structure
src
| - client
| | - components
| | - config
| | | - store.js
| | | ...
| | - containers
| | - middlewares
| | | - reactRouterDataLoading.js // <-- this file must be written by yourself.
                                  // It is responsible to trigger the epics for the requested page url
                                  // and reacts on react-router-redux action-types which are fired
                                  // by the middleware of this library
| | - modules
| - server
| | - index.js

Server

// express server
...
import { SSR } from 'redux-observables-server-side-rendering'

app.use('*', (req, res) => {

  ...
  const history = createMemoryHistory({
    initialEntries: [req.originalUrl],
  })

  const reduxObservablesSSR = new SSR(req.originalUrl)
    .onLoad(store => {
      processApp(store, history, res, req, cacheName) // helper function to renderToString(YourApp)
    })
    .onRedirect((store, { status = 301, redirectUrl }) => { // react on redirects
      res.redirect(status, redirectUrl)
    })
    .onNotFound((store, { status = 404 }) => {        // react on page notFound
      res.status(status)                              // set response status code
      processApp(store, history, res, req, cacheName) // helper function to renderToString(YourApp)
    })

    const initialState = { ... }
    const store = configureStore(initialState, {
      ... // your store configuration
      middlewares: [reduxObservablesSSR.middleware()],
      epicOptions: {
        dependencies: reduxObservablesSSR,
      },
    })

    /* the SSR module creates an initial action in the following form:
     * 
     * {
     *   type: '@@router/LOCATION_CHANGE', <-- react-router-redux specific action type
     *   payload: {
     *     pathname: 'current/location/on/my/website', <-- req.originalUrl
     *   },
     * }
     * 
     * the initial action will be fired with the following command and could be handled
     * from a middleware which triggers the initial epic action to fetch required data.
     * (this middleware have to be written by yourself and is not included in this library)
     */
    reduxObservablesSSR.dispatchInitialAction(store)

})

Client

To make ssr with redux-observables work, we have to configure the store:

// store.js
...
// this mock is needed for the client.js to work
import { SSR_DEPENDENCIES_MOCK } from 'redux-observables-server-side-rendering'

const initalOptions = {
  middlewares: [],
  epicOptions: {
    dependencies: SSR_DEPENDENCIES_MOCK,
  },
  history: null,
}
export const configureStore = (initialState = {}, options = initialOptions) => {
  let middlewares = []
  
  ...
  
  // hand over the instance of the SSR object (namend reduxObservablesSSR in the server implementation) 
  // to the epic middleware as dependency.
  // This will make the object available in all of your epic's as third argument.
  middlewares = [...middlewares, createEpicMiddleware(rootEpic, _options.epicOptions)]
  
  ...
  
  // its important that the ssr middleware stands at the last place of the array
  if (_options.middlewares.length > 0)
    middlewares = [...middlewares, ..._options.middlewares]

  const store = createStore(
    rootReducer,
    initialState,
    applyMiddleware(...middlewares)
  )

  return store
}