How to use React SSR for just a single route?


#1

The entirety of my app is traditional client-side React, but I have one route/URL in particular that I want to use SSR for, so the user sees something come up much quicker. What can I use, without interfering with the rest of my application?


#2

Can you not set up SSR the normal way, but only render if the route matches the one you want?


#3

Not even sure what “the normal way” is. :wink:


#4

What are you using? react + redux + react-router?


#5

I’m about to try and do the same thing. I’ll let you know what I find.


#6

I can help as I have accomplished this, but I need to know what you’re using for routing at the very least.


#7

Right now I just have a client-side routing meteor app with react-router V4.


#8

Check out this example here, except throw an if statement to only do this if it matches the route you want


#9

Same here as @a.com, but I’m using Flow Router for client side routing.


#10

Won’t be able to help you out there as I haven’t used flowrouter in about 2 years, but the example I provided may help you get a general idea.


#11

Thanks, Brendan! I’m sure I can piece something together. I’ll check it out when I get a few mins.


#12

We’re on Blaze, but using FR, so I think most of this will make sense:

import { WebApp } from 'meteor/webapp';
import { SSR } from 'meteor/meteorhacks:ssr';

const serverRendering = (req, res, next) => {
  const pathName = req.originalUrl;
  if (pathName.includes('/theTarget/')) {
    // If the path matches
    const htmlContent = SSR.render('someTemplate', { data });
    // This should be a template literal but the formatting was getting messed up
    const html = '
      <!html>
      <head>
        <!-- header stuff -->
      </head>
      <body>
        ${htmlContent}
      </body>
    ';
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/html');
    res.end(html);
  } else {
    // Otherwise, just let your default router handle it
    next();
  }
});

WebApp.connectHandlers.use(serverRendering);

#14

Great, so I got some basic output thanks to piecing stuff together from the various code snippets above. Thanks! Though the next challenge is: how (if it’s even possible) do I get this to be interactive (event handling, state, etc)? Bear with me, I have zero experience with SSR. AFAIK, the way this works is:

  1. Server quickly renders out static HTML to the browser.
  2. Client then loads up, doesn’t have to draw anything since the server already did it, but provides all the reactivity/interactivity.

I’m not sure how to get this working. Below is what I have so far. I think I need a way to call next(), so that the client side / Flow Router can detect the /ssr route and render the exact same thing… yes?

import React from 'react';
import { WebApp } from 'meteor/webapp';
import { renderToString } from 'react-dom/server';

class Clicker extends React.Component {
  state = {
    clicker: 0,
  };

  increase = () => {
    this.setState({ clicker: this.state.clicker + 1 });
  };

  render() {
    return (
      <div>
        <div onClick={this.increase}>Click this! {this.state.clicker}</div>
      </div>
    );
  }
}

WebApp.connectHandlers.use('/ssr', function(req, res, next) {
  const html = renderToString(<Clicker />);

  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/html');
  res.end(html);
});

#15

Why did you end up using connectHandlers over onPageLoad?


#16

Now that I’m seeing your use case better, I’m not sure how easily you will be able to hydrate/provide the necessary interactions using the method I posted above. That is definitely geared towards a static html experience. Not saying it can’t be done, that’s just not how we use the implementation I posted. :slight_smile:


#17

Because I like keeping my app lean (i.e. don’t add packages unless I absolutely need them). And meteor/webapp is there for free.


#18

Yeah, with Flow Router handling the low level setup of the routes and injecting an <App /> into the react-root div, I don’t think this will work. I’ll need to ditch Flow Router if I want to make one of my routes SSR.


#19

@ffxsam there used to be a Flowrouter-SSR implementation IIRC. Maybe there is something in there that could help?! https://github.com/kadirahq/flow-router/tree/ssr