react
ASP.NET Core,  React

React with Server Side Rendering, ASP.NET Core

React with Server Side Rendering is part 4 of a 5 parts React with ASP.NET Core series. This series will show you the setup necessary for building React single page application with routing and server-side rendering.

With the advance of technologies and more power devices/computers, websites have evolved from simple static files, server side rendering to generate static HTML pages, dynamic HTML, to now dynamically update web-page at the browser with client side rendering for an app like experience.
So do we still need server side rendering or is it a thing in the past? Not quite. In fact, server side rendering still have an important role that compliments client side rendering. How can server side rendering help? Let’s first look at the short comings of using client side rendering:

  1. Poor support for search engine optimization (SEO)
  2. Initial load time is significantly higher (which also impact SEO now that Google wants fast loading websites)

Unless the website is for internal use by an organization or it’s a well known website providing services that support your daily routines (like banking), these short comings can have a significant impact on the website. Without good support for SEO, Internet users won’t even be able to find you through search engines like Google, Yahoo and others. Fast response from websites are also what users expect nowadays. If it takes too much time loading, users could very well give up and browse away already, without seeing the very first page. If users cannot reach your website, no matter how well built it is, they cannot see nor use it.

Compliments React with server side rendering

Server side rendering will play a different role now, not like what it used to be. Instead of serving every pages to the browser, server side rendering now renders the initial page request and provides the data needed for client side rendering.

So what’s the improvement? When a user requests the very first page from the website, the server will fully render this first page, return to the user and the browser would be able to show your page to the user right away, while the browser is still downloading the client side javascript for execution. This first page would also contains the initial data needed so that client side rendering does not need another request to retrieve data. Moreover, this facilitates full support of SEO, like traditional server side rendering. Once the browser finishes downloading and executes the client side javascript bundle, client side rendering would then take over the control and serve all subsequent actions or page requests with very fast response.

Note: The user won’t be able to start interacting with the webpage until client side rendering has completed. However, with the combine use of server side rendering, the first meaningful paint would be much faster and scoring a much better perceptual speed index. That provides a better first load experience for the users and will result in better ranking in search engines like Google.

React with server side rendering, Get started

Goal: To run react with server side rendering in a simple setup to pre-render the page and provide data hydration.

Base project code: Example codes from React with Redux, Get started, with ASP.NET Core serves as the starting point. (Rendering a simple HelloWorld component with Redux). The project structure looks like this:
React with server side rendering: project structure

React side

Add following npm packages to package.json:

Update the retrieveData() async method at async_thunks.ts as follow:

This method is responsible to retrieve data from server. Used in both client side & server side rendering. Highlighted lines are new code added to enable fetch at Node.js. addTask() is also used to keep a collection of asynchronous calls so that the server side rendering will wait for all these necessary asynchronous calls to complete, before performing the final rendering. This is important as you can see in this example, server side rendering needs to wait for retrieveData() to complete, otherwise, there will be no data to render the HelloWorld component.

 

Create file entry-server.tsx in the Scripts folder as the entry point of server side rendering for webpack to create a server bundle.

This will create the entry point for ASP.NET Core to invoke.
Let’s make a quick update on the entry.tsx (client side), replace file with following codes

This update makes use of the hydrate function (design to work with server side rendering) instead of render. ReduxInitialState at the highlighted line is the Redux data passed by server side rendering for data hydration.
Now let’s add configuration for webpack to create both the client & server bundles. Replace webpack.config.js with the codes below:

This webpack config will generate two bundles. bundle.js for client side rendering (used by browsers), located at wwwroot/dist for public access. bundle-server.js for server side rendering, located at Scripts/Dist for server use.

ASP.NET Core side

Finally, we will work on the ASP.NET Core side to have Index.cshtml (Home page using basic MVC model) invokes the server side entry point.
The default NuGet package Microsoft.AspNetCore.All already contains the SpaServices libraries needed.
Let’s first enable the tag helper of SpaServices. Create file _ViewImports.cshtml in the Views folder and add the following line:

Now replace the file  Index.cshtml in the Views/Home folder with following code:

This tells ASP.NET Core where the export function of the server bundle is. And ASP.NET Core will pass it to Node.js for execution. asp-prerender-data is a custom data object you can pass to the export function. Don’t need to use it so just pass a dummy object to show case the attribute.

All done and it should be running react with server side rendering now. ASP.NET Core will invoke the server side rendering, render the HelloWorld component inside the content tag and return to the browser, ready to display.

 

Example code for Part 4: React with server side rendering is available at Github.

More Read

React with ASP.NET Core series – Part 5: React with Routing, enabling SPA using redux-little-router, Get Started with ASP.NET Core

React with ASP.NET Core series – Part 3: React with Redux, Get started, with ASP.NET Core

6 Comments

  • Nvn

    Hey, thx for these articles . They’ve been really helpful and detailed. I’m moving from desktop and server side programming to this.
    Also could you recommend some other learning sources on React frontend? Something on the architecture and making reusable components?

    • Alan Chan

      Thanks for leaving comments. Great to hear that they are helpful.
      definitely visit ReactJs official website. Getting in-depth knowledge with React is critical because there are plenty of ways to implement React components but doing them right can make a big difference in performance.
      The standard way of building reusable components in React would be composition instead of inheritance.

  • Yehuda Makarov

    Hey, thank you very much for this. Microsoft documentation around the tag helpers isn’t very good, and it looks like a lot of it actually doesn’t exist.

    What’s the difference between asp-prerender-module and -export. You use both but I e seen other examples only using one. And where is the documentation? How did you figure that stuff out?

    • Alan Chan

      Hi Yehuda,

      asp-prerender-module specifies the javascript file (bundled from entry_server.tsx) that has the server rendering function.
      asp-prerender-export specifies the name of the javascript function. (with use of this tag helper, you can define and use multiple rendering functions in the same file)

      when asp-prerender-export is not used, the default export function from the javascript file will be used.

      I think it was used in earlier version of SpaServices examples but had since been updated and used default export function instead.

      thanks for your comments.

  • Yehuda Makarov

    Actually, the tag helper syntax isn’t really in the documentation very well. They reference class properties on the PrerenderTagHelper Class. Asp-prerender-module in the html tag maps to the class property: https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.spaservices.prerendering.prerendertaghelper.modulename?view=aspnetcore-2.2#Microsoft_AspNetCore_SpaServices_Prerendering_PrerenderTagHelper_ModuleName.

    And this is the info the exportName property that is mapped by the asp-prerender-export html property.

    – If set, specifies the name of the CommonJS export that is the prerendering function to execute. If not set, the JavaScript module’s default CommonJS export must itself be the prerendering function.

Leave a Reply

Your email address will not be published. Required fields are marked *