{"id":17654,"date":"2017-06-30T12:15:35","date_gmt":"2017-06-30T09:15:35","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=17654"},"modified":"2017-06-29T14:21:43","modified_gmt":"2017-06-29T11:21:43","slug":"server-rendering-react-rails","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/","title":{"rendered":"Server Rendering React on Rails"},"content":{"rendered":"<p>React apps give us incredible power in the browser, and with the <a href=\"https:\/\/github.com\/shakacode\/react_on_rails\">react_on_rails<\/a> gem from the folks at <a href=\"http:\/\/www.shakacode.com\/\">ShakaCode<\/a>, we now have an easy way to use React inside of our new and existing Rails apps. In a previous article, I talked about how to get up and running with <a href=\"https:\/\/www.webcodegeeks.com\/ruby\/using-react-inside-rails-apps\/\">React in your Rails app<\/a>.<\/p>\n<p>In this article, we are going to talk about doing server rendering with our React components inside of Rails. An article by Tom Dale talks about <a href=\"http:\/\/tomdale.net\/2015\/02\/youre-missing-the-point-of-server-side-rendered-javascript-apps\/\">misconceptions about server rendering<\/a>. With so many misconceptions, what is it and why would you want it?<\/p>\n<p>The app we\u2019ll be discussing <a href=\"https:\/\/github.com\/leighhalliday\/home-demo\">is located here<\/a>.<\/p>\n<h2>What Is Server Rendering?<\/h2>\n<p>Usually with React apps, the HTML source returned from the server is extremely minimal, and then it is React itself that builds out the DOM that you end up seeing in the browser. This is in contrast to a traditional server-rendered website where the server generates the HTML, and when it arrives to the browser, it\u2019s already fully fleshed out.<\/p>\n<p>What server rendering in React means is to allow the server to prerender the React components server-side before sending them to the browser. When the HTML arrives to the browser, it is displayed immediately as if it were server-rendered, and then React takes over from there. This can provide a few benefits, but as we\u2019ll also see, it doesn\u2019t come for free.<\/p>\n<p>Benefits to this approach include the potential for better SEO. Crawlers don\u2019t need to have JavaScript enabled to see the contents of the page. If you perform a <code>curl<\/code> call from your terminal, you\u2019ll actually see real HTML as opposed to a <code>&lt;div&gt;<\/code> tag waiting to be populated with content.<\/p>\n<p>Another benefit is that if your components take time to \u201cboot up\u201d or initialize, it can provide a better experience in that they\u2019ll be able to see the content of the page more immediately.<\/p>\n<h2>Simple Server Rendering<\/h2>\n<p>To get up and running with server rendering with the <code>react_on_rails<\/code> gem, it\u2019s as easy as providing an additional parameter to the <code>react_component<\/code> call and ensuring that you have installed <code>react_on_rails<\/code> using the <code>--node<\/code> option. <code>react_on_rails<\/code> uses a library called <a href=\"https:\/\/rubygems.org\/gems\/mini_racer\">MiniRacer<\/a> to execute JS from within Ruby.<\/p>\n<pre class=\"brush:php\">&lt;%= react_component(\"MyComponent\", props: {}, prerender: true) %&gt;<\/pre>\n<p>By changing <code>prerender<\/code> to true, our server produces the following HTML:<\/p>\n<pre class=\"brush:xml\">&lt;script type=\"application\/json\" class=\"js-react-on-rails-component\" data-component-name=\"MyComponent\" data-trace=\"true\" data-dom-id=\"MyComponent-react-component-a72f0441-f121-4ba5-abc8-6b30dfc60273\"&gt;{}&lt;\/script&gt;\r\n\r\n&lt;div id=\"MyComponent-react-component-a72f0441-f121-4ba5-abc8-6b30dfc60273\"&gt;\r\n  &lt;h1 data-reactroot=\"\" data-reactid=\"1\" data-react-checksum=\"-22604146\"&gt;\r\n    Welcome to My Component\r\n  &lt;\/h1&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>It contains the necessary script tag and ids to allow React (via <code>react_on_rails<\/code>) to take over in the client, but you can see that the <code>h1<\/code> tag arrived pregenerated.<\/p>\n<p>The actual component in this case looks no different from your typical React component:<\/p>\n<pre class=\"brush:java\">import React from 'react';\r\n\r\nexport default class MyComponent extends React.Component {\r\n  render() {\r\n    return (\r\n      &lt;h1&gt;Welcome to My Component&lt;\/h1&gt;\r\n    );\r\n  }\r\n}<\/pre>\n<p>This may work for simple setups, but when you are dealing with ReactRouter and Redux, you\u2019ll probably want to opt for a more complicated setup which we\u2019ll discuss below.<\/p>\n<h2>More Setup Needed<\/h2>\n<p>The first issue I ran into when trying to convert a non-server-rendered React app to be server rendered was that I was using <code>BrowserRouter<\/code> to handle the routing. This is fine in the browser but caused all sorts of issues being executed on the server. I was going to need a slightly different setup for doing server rendering. I would do this through having two separate webpack configs, Procfile entries, and \u201cregistration\u201d entry points.<\/p>\n<p>My <code>Procfile.dev<\/code> file in the root folder of my Rails app had entries for \u2018web\u2019 and \u2018client\u2019. I added a third for \u2018server\u2019.<\/p>\n<pre class=\"brush:php\">web: rails s -p 3000\r\nclient: sh -c 'rm app\/assets\/webpack\/* || true &amp;&amp; cd client &amp;&amp; bundle exec rake react_on_rails:locale &amp;&amp; yarn run build:development:client'\r\nserver: cd client &amp;&amp; yarn run build:development:server<\/pre>\n<p>Inside of the <code>client\/package.json<\/code> file, I renamed my \u201cscript\u201d entries to clearly mention either client or server.<\/p>\n<pre class=\"brush:php\">\"scripts\": {\r\n  \"build:production:client\": \"NODE_ENV=production webpack --config webpack.client.config.js\",\r\n  \"build:production:server\": \"NODE_ENV=production webpack --config webpack.server.config.js\",\r\n  \"build:development:client\": \"webpack -w --config webpack.client.config.js\",\r\n  \"build:development:server\": \"webpack -w --config webpack.server.config.js\"\r\n}<\/pre>\n<p>For webpack, I took a copy of the client version and modified them both slightly to point at different registration files (one for client and one for server). This is found under the <code>entry<\/code> key and the full files can be <a href=\"https:\/\/github.com\/leighhalliday\/home-demo\/tree\/master\/client\">found here<\/a>.<\/p>\n<h2>Router and Server Rendering<\/h2>\n<p>In the client version of React, I am using <code>BrowserRouter<\/code> to handle routing. This won\u2019t work on the server because the JavaScript is executing out of the context of a browser, without access to the <code>window<\/code> or the <code>document<\/code> objects.<\/p>\n<p>For the server, we can use <code>StaticRouter<\/code> to kick things off, and then the <code>BrowserRouter<\/code> will take over once on the client.<\/p>\n<h3>The client version<\/h3>\n<p>For the client version, the registration file looks like this:<\/p>\n<pre class=\"brush:java\">\/\/ client\/app\/bundles\/Home\/startup\/clientRegistration.jsx\r\nimport ReactOnRails from 'react-on-rails';\r\nimport HomeApp from '.\/ClientHomeApp';\r\n\r\nReactOnRails.register({\r\n  HomeApp\r\n});<\/pre>\n<p>And the <code>ClientHomeApp<\/code> sets up routing and the Redux store.<\/p>\n<pre class=\"brush:java\">\/\/ client\/app\/bundles\/Home\/startup\/ClientHomeApp.jsx\r\nimport React from 'react';\r\nimport { Provider } from 'react-redux';\r\nimport { BrowserRouter } from 'react-router-dom';\r\n\r\nimport configureStore from '..\/store\/homeStore';\r\nimport routes from '..\/routes\/routes';\r\n\r\nexport default (props, _railsContext) =&gt; {\r\n  const store = configureStore(props);\r\n\r\n  return (\r\n    &lt;Provider store={store}&gt;\r\n      &lt;BrowserRouter&gt;\r\n        {routes}\r\n      &lt;\/BrowserRouter&gt;\r\n    &lt;\/Provider&gt;\r\n  );\r\n};<\/pre>\n<h3>The server version<\/h3>\n<p>The server version of our registration file looks very similar, only pointing to a different <code>ServerHomeApp<\/code> file.<\/p>\n<pre class=\"brush:java\">\/\/ client\/app\/bundles\/Home\/startup\/serverRegistration.jsx\r\nimport ReactOnRails from 'react-on-rails';\r\nimport HomeApp from '.\/ServerHomeApp';\r\n\r\nReactOnRails.register({\r\n  HomeApp\r\n});<\/pre>\n<p>The <code>ServerHomeApp<\/code> is where things differ slightly. Here we will swap out the <code>BrowserRouter<\/code> for a <code>StaticRouter<\/code> and use the handy <code>railsContext<\/code> variable to provide the necessary routing context to ReactRouter so it can determine which route to display. This is normally grabbed from the browser directly, but without a browser it\u2019s up to us to provide that missing information.<\/p>\n<pre class=\"brush:java\">import { Provider } from 'react-redux';\r\nimport { StaticRouter } from 'react-router';\r\n\r\nimport configureStore from '..\/store\/homeStore';\r\nimport routes from '..\/routes\/routes';\r\n\r\nexport default (props, railsContext) =&gt; {\r\n  const store = configureStore(props);\r\n  const { location } = railsContext;\r\n  const context = {};\r\n\r\n  return (\r\n    &lt;Provider store={store}&gt;\r\n      &lt;StaticRouter location={location} context={context}&gt;\r\n        {routes}\r\n      &lt;\/StaticRouter&gt;\r\n    &lt;\/Provider&gt;\r\n  );\r\n};<\/pre>\n<p>`<\/p>\n<p>If you are interesting in what the <code>{routes}<\/code> imported into the router look like, they are as follows (and are thankfully shared across both versions):<\/p>\n<pre class=\"brush:java\">\/\/ client\/app\/bundles\/Home\/routes\/routes.jsx\r\nimport { Route, Switch } from 'react-router';\r\n\r\nimport HomeContainer from '..\/containers\/HomeContainer';\r\nimport NewHouseContainer from '..\/containers\/NewHouseContainer';\r\nimport HouseInfoContainer from '..\/containers\/HouseInfoContainer';\r\n\r\nexport default (\r\n  &lt;Switch&gt;\r\n    &lt;Route path=\"\/\" exact component={HomeContainer} \/&gt;\r\n    &lt;Route path=\"\/houses\/new\" component={NewHouseContainer} \/&gt;\r\n    &lt;Route path=\"\/houses\/:id\" component={HouseInfoContainer} \/&gt;\r\n  &lt;\/Switch&gt;\r\n);<\/pre>\n<p>For more details on server-side routing with ReactRouter, feel free to <a href=\"https:\/\/reacttraining.com\/react-router\/web\/guides\/server-rendering\">check out their article<\/a>.<\/p>\n<p>!Sign up for a free Codeship Account<\/p>\n<h2>Hydrating our Redux Store<\/h2>\n<p>The next part of the puzzle is to <a href=\"http:\/\/redux.js.org\/docs\/recipes\/ServerRendering.html\">hydrate the initial Redux state<\/a> when doing server rendering. This is done fairly easily thanks to the <code>react_on_rails<\/code> gem.<\/p>\n<p>We already have the ability to pass props when rendering React components in our Rails views. In a simple case, this is passed directly to our component, but with React we can use it to set the Redux store\u2019s initial state.<\/p>\n<p>It starts in the controller by providing the view with the data it needs:<\/p>\n<pre class=\"brush:php\">house = House.find(params[:id])\r\n@house_hash = HouseSerializer.new(house).serializable_hash<\/pre>\n<p>In the view, we pass the <code>@house_hash<\/code> on to our component (note that we have <code>prerender: true<\/code>):<\/p>\n<pre class=\"brush:php\">react_component('HomeApp', props: {home: {house: @house_hash}}, prerender: true)<\/pre>\n<p>In both the <code>ClientHomeApp<\/code> and <code>ServerHomeApp<\/code> files, they receive these props and call a <code>configureStore<\/code> function.<\/p>\n<pre class=\"brush:php\">export default (props, railsContext) =&gt; {\r\n  const store = configureStore(props);\r\n  \/\/ ...\r\n}<\/pre>\n<p>Finally, we use the <code>createStore<\/code> function from Redux, passing in our props as initial state.<\/p>\n<pre class=\"brush:java\">\/\/ client\/app\/bundles\/Home\/store\/homeStore.jsx\r\nimport { createStore, combineReducers, applyMiddleware } from 'redux';\r\nimport { routerReducer } from 'react-router-redux';\r\nimport thunk from 'redux-thunk'\r\n\r\nimport homeReducer from '..\/reducers\/homeReducer';\r\n\r\nconst configureStore = (railsProps) =&gt; (\r\n  createStore(\r\n    combineReducers({\r\n      home: homeReducer,\r\n      routing: routerReducer\r\n    }),\r\n    railsProps, \/\/ our initial state\r\n    applyMiddleware(thunk)\r\n  )\r\n);\r\n\r\nexport default configureStore;<\/pre>\n<p>Now that the store has its initial state set, as Redux passes this state as props to our \u201cconnected\u201d component, we can check if these props contain the house we need and thereby avoid having to fetch it via an AJAX call to the server.<\/p>\n<pre class=\"brush:php\">\/\/ Taken from client\/app\/bundles\/Home\/components\/HouseInfo.jsx\r\ncomponentWillMount() {\r\n  \/\/ Only load the house from server if it isn't already passed in as a prop\r\n  if (this.needHouse(this.props)) {\r\n    this.props.loadHouse(this.props.match.params.id);\r\n  }\r\n}<\/pre>\n<h2>Conclusion<\/h2>\n<p>In this article, we discussed what server rendering for a React (on Rails) app is and what some of the benefits are. We also saw that it increases the complexity by introducing additional webpack configuration and routing variations on the client versus the server.<\/p>\n<p>In my opinion, I would avoid the extra headache unless you see that it provides real benefits to either your users or to your SEO rankings.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"https:\/\/blog.codeship.com\/server-rendering-react-on-rails\/\">Server Rendering React on Rails<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\">WCG partner<\/a> Leigh Halliday at the <a href=\"http:\/\/blog.codeship.com\/\">Codeship Blog<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>React apps give us incredible power in the browser, and with the react_on_rails gem from the folks at ShakaCode, we now have an easy way to use React inside of our new and existing Rails apps. In a previous article, I talked about how to get up and running with React in your Rails app. &hellip;<\/p>\n","protected":false},"author":113,"featured_media":4127,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[95,468],"class_list":["post-17654","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ruby","tag-rails","tag-react"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Server Rendering React on Rails - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"React apps give us incredible power in the browser, and with the react_on_rails gem from the folks at ShakaCode, we now have an easy way to use React\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Server Rendering React on Rails - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"React apps give us incredible power in the browser, and with the react_on_rails gem from the folks at ShakaCode, we now have an easy way to use React\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2017-06-30T09:15:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/rubyonrails-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Leigh Halliday\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@leighchalliday\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Leigh Halliday\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/\"},\"author\":{\"name\":\"Leigh Halliday\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/e496b17f78cdca27723b8e225dc6ab6b\"},\"headline\":\"Server Rendering React on Rails\",\"datePublished\":\"2017-06-30T09:15:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/\"},\"wordCount\":1078,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/rubyonrails-logo.jpg\",\"keywords\":[\"Rails\",\"React\"],\"articleSection\":[\"Ruby\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/\",\"name\":\"Server Rendering React on Rails - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/rubyonrails-logo.jpg\",\"datePublished\":\"2017-06-30T09:15:35+00:00\",\"description\":\"React apps give us incredible power in the browser, and with the react_on_rails gem from the folks at ShakaCode, we now have an easy way to use React\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/rubyonrails-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/rubyonrails-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ruby\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/ruby\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Server Rendering React on Rails\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/e496b17f78cdca27723b8e225dc6ab6b\",\"name\":\"Leigh Halliday\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bd40251a1acc424c292c35a3485264a801efa20efa7063c3e320a0a354ddafac?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bd40251a1acc424c292c35a3485264a801efa20efa7063c3e320a0a354ddafac?s=96&d=mm&r=g\",\"caption\":\"Leigh Halliday\"},\"description\":\"Leigh is a developer at theScore. He writes about Ruby, Rails, and software development on his personal site.\",\"sameAs\":[\"http:\/\/www.leighhalliday.com\/\",\"https:\/\/x.com\/leighchalliday\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/leigh-halliday\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Server Rendering React on Rails - Web Code Geeks - 2026","description":"React apps give us incredible power in the browser, and with the react_on_rails gem from the folks at ShakaCode, we now have an easy way to use React","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/","og_locale":"en_US","og_type":"article","og_title":"Server Rendering React on Rails - Web Code Geeks - 2026","og_description":"React apps give us incredible power in the browser, and with the react_on_rails gem from the folks at ShakaCode, we now have an easy way to use React","og_url":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2017-06-30T09:15:35+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/rubyonrails-logo.jpg","type":"image\/jpeg"}],"author":"Leigh Halliday","twitter_card":"summary_large_image","twitter_creator":"@leighchalliday","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Leigh Halliday","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/"},"author":{"name":"Leigh Halliday","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/e496b17f78cdca27723b8e225dc6ab6b"},"headline":"Server Rendering React on Rails","datePublished":"2017-06-30T09:15:35+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/"},"wordCount":1078,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/rubyonrails-logo.jpg","keywords":["Rails","React"],"articleSection":["Ruby"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/","url":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/","name":"Server Rendering React on Rails - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/rubyonrails-logo.jpg","datePublished":"2017-06-30T09:15:35+00:00","description":"React apps give us incredible power in the browser, and with the react_on_rails gem from the folks at ShakaCode, we now have an easy way to use React","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/rubyonrails-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/rubyonrails-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/ruby\/server-rendering-react-rails\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Ruby","item":"https:\/\/www.webcodegeeks.com\/category\/ruby\/"},{"@type":"ListItem","position":3,"name":"Server Rendering React on Rails"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/e496b17f78cdca27723b8e225dc6ab6b","name":"Leigh Halliday","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/bd40251a1acc424c292c35a3485264a801efa20efa7063c3e320a0a354ddafac?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bd40251a1acc424c292c35a3485264a801efa20efa7063c3e320a0a354ddafac?s=96&d=mm&r=g","caption":"Leigh Halliday"},"description":"Leigh is a developer at theScore. He writes about Ruby, Rails, and software development on his personal site.","sameAs":["http:\/\/www.leighhalliday.com\/","https:\/\/x.com\/leighchalliday"],"url":"https:\/\/www.webcodegeeks.com\/author\/leigh-halliday\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/17654","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/113"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=17654"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/17654\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/4127"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=17654"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=17654"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=17654"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}