1"use strict";(self.webpackChunkgatsby_starter_default=self.webpackChunkgatsby_starter_default||[]).push([[1546],{45277:function(e,n,a){a.r(n),a.d(n,{Head:function(){return h},default:function(){return m}});var t=a(28453),l=a(96540);function s(e){const n=Object.assign({h1:"h1",a:"a",span:"span",div:"div",p:"p",svg:"svg",path:"path",strong:"strong",h2:"h2",ul:"ul",li:"li",ol:"ol",h3:"h3",blockquote:"blockquote",h4:"h4",h5:"h5",em:"em",img:"img",hr:"hr",h6:"h6"},(0,t.R)(),e.components);return l.createElement(l.Fragment,null,l.createElement(n.h1,{id:"upgrading-react-on-rails",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-react-on-rails","aria-label":"upgrading react on rails permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading React on Rails"),"\n",l.createElement(n.div,{className:"markdown-alert markdown-alert-note",dir:"auto"},"\n",l.createElement(n.p,{className:"markdown-alert-title",dir:"auto"},l.createElement(n.svg,{className:"octicon",viewBox:"0 0 16 16",width:"16",height:"16","aria-hidden":"true"},l.createElement(n.path,{d:"M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"})),"NOTE"),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Summary for AI agents:")," Use this page when the user is upgrading between React on Rails versions (e.g., v13 â v14). For upgrading from OSS to Pro, see ",l.createElement(n.a,{href:"/linked-assets/178cee18ad3302a36139f1f741b8c2b9/upgrading-to-pro.md"},"Upgrade to Pro"),". For upgrading between ",l.createElement(n.strong,null,"React on Rails Pro versions"),", see ",l.createElement(n.a,{href:"/linked-assets/c1ca97ca44796960756f2a6cdec31f5f/updating.md"},"Upgrading React on Rails Pro")," â Pro upgrades are coupled Ruby + JavaScript changes and need lockfile updates on both sides. For migrating from the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react-rails</code>'}})," gem, see ",l.createElement(n.a,{href:"/linked-assets/e66127e3777c8cd54892386e80bbfaba/migrating-from-react-rails.md"},"Migrating from react-rails"),". Check the ",l.createElement(n.a,{href:"/linked-assets/b5c7fdb9a628e82c3afdda12830a0c77/index.md"},"release notes")," for version-specific breaking changes."),"\n"),"\n",l.createElement(n.h2,{id:"need-help-migrating",style:{position:"relative"}},l.createElement(n.a,{href:"#need-help-migrating","aria-label":"need help migrating permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Need Help Migrating?"),"\n",l.createElement(n.p,null,"If you would like help in migrating between React on Rails versions or help with implementing server rendering, please contact ",l.createElement(n.a,{href:"mailto:[email protected]"},"[email protected]")," for more information about our ",l.createElement(n.a,{href:"/linked-assets/5f3eacdd52b97cebdce257aa7836a6e1/react-on-rails-pro.md"},"React on Rails Pro Support"),"."),"\n",l.createElement(n.p,null,"We specialize in helping companies to quickly and efficie
1ntly upgrade. The older versions use the Rails asset pipeline to package client assets. The current and recommended way is to use Webpack 4+ for asset preparation. You may also need help migrating from the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">rails/webpacker</code>'}}),"'s Webpack configuration to a better setup ready for Server Side Rendering."),"\n",l.createElement(n.h2,{id:"v15-retraction-notice",style:{position:"relative"}},l.createElement(n.a,{href:"#v15-retraction-notice","aria-label":"v15 retraction notice permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"v15 Retraction Notice"),"\n",l.createElement("span",{id:"v15-retraction-notice"}),"\n",l.createElement(n.p,null,"React on Rails v15.0.0 was retracted due to API design issues. When upgrading from v14 or earlier, skip v15 and upgrade directly to v16 or a later supported release. Historical v15 material remains available for maintaining older applications: ",l.createElement(n.a,{href:"https://github.com/shakacode/react_on_rails/tree/15.0.0/docs"},"React on Rails 15.0.0 docs")," and ",l.createElement(n.a,{href:"https://github.com/shakacode/react_on_rails/tree/15.0.0"},"React on Rails 15.0.0 code"),"."),"\n",l.createElement(n.h2,{id:"general-upgrade-process",style:{position:"relative"}},l.createElement(n.a,{href:"#general-upgrade-process","aria-label":"general upgrade process permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"General Upgrade Process"),"\n",l.createElement(n.p,null,"After upgrading to any major version, always run the generator to get the latest defaults:"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">rails generate react_on_rails:install</code></pre></div>'}}),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"â ï¸ Important"),": Review generated changes carefully before applying to avoid overwriting custom configurations. The generator updates:"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">bin/dev</code>'}})," (improved development workflow)"),"\n",l.createElement(n.li,null,"webpack configurations"),"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">shakapacker.yml</code>'}})," settings"),"\n",l.createElement(n.li,null,"other configuration files"),"\n"),"\n",l.createElement(n.h2,{id:"pro-users-coupled-ruby--javascript-upgrade",style:{position:"relative"}},l.createElement(n.a,{href:"#pro-users-coupled-ruby--javascript-upgrade","aria-label":"pro users coupled ruby javascript upgrade permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Pro Users: Coupled Ruby + JavaScript Upgrade"),"\n",l.createElement(n.p,null,"React on Rails Pro versions are a ",l.createElement(n.strong,null,"coupled Ruby + JavaScript upgrade"),": the gem\n(",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_on_rails_pro</code>'}}),"), the npm packages (",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react-on-rails-pro</code>'}}),", optionally\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react-on-rails-pro-node-renderer</code>'}})," and ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react-on-rails-rsc</code>'}}),"), ",l.createElement(n.strong,null,"and")," both\nlockfiles (",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Gemfile.lock</code>'}})," plus ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">yarn.lock</code>'}})," / ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">package-lock.json</code>'}})," / ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">pnpm-lock.yaml</code>'}}),")\nmust move together. The gem and the npm package also use different prerelease\nformats (",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">16.7.0.rc.0</code>'}})," on RubyGems vs ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">16.7.0-rc.0</code>'}})," on npm)."),"\n",l.createElement(n.p,null,"See ",l.createElement(n.a,{href:"../../pro/updating.md#coupled-pro-upgrade-checklist"},"Upgrading React on Rails Pro â Coupled Pro Upgrade Checklist"),"\nfor the full step-by-step. Following that checklist is required for Pro upgrades\nto avoid PRs that pass loose installs locally and then fail CI under frozen-lockfile\ninstall."),"\n",l.createElement(n.h2,{id:"upgrade-preflight",style:{position:"relative"}}
1,l.createElement(n.a,{href:"#upgrade-preflight","aria-label":"upgrade preflight permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrade Preflight"),"\n",l.createElement(n.p,null,"Before changing versions, check these first:"),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Ruby and Node requirements"),": React on Rails v17 requires Ruby 3.3+ and Node 18+. The default React on Rails Pro Node renderer resolves Fastify 5 and requires Node 20+ at startup. Its ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">engines.node</code>'}})," floor of Node 18.19.0+ applies only when you use the documented Fastify 4-compatible dependency overrides. React on Rails v16 remains the upgrade path for apps that need older Ruby versions."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Bundler age"),": legacy apps may have lockfiles created by Bundler 1.x. Those lockfiles can fail on modern Ruby before the React on Rails upgrade even starts."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Rails version"),": current ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_on_rails</code>'}})," requires Ruby 3.3+, which is incompatible with Rails < 7.0. Older Rails apps need a Rails upgrade first."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Asset stack"),": if the app still uses ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpacker</code>'}}),", upgrade to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">shakapacker</code>'}})," first."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Version pinning"),": use exact gem and npm package versions for React on Rails-related packages. Avoid ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">^</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">~</code>'}}),", or ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">*</code>'}}),"."),"\n"),"\n",l.createElement(n.p,null,"If your app is both Ruby/Bundler-old and Webpacker-old, do those upgrades first. Trying to jump directly from an older Rails / Webpacker 3 / Bundler 1 stack to current React on Rails is usually more than one migration."),"\n",l.createElement(n.p,null,"If the first failure is a Bundler 1.x lockfile, refresh that lockfile with Bundler 2.x before changing React on Rails:"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">gem <span class="token function">install</span> bundler <span class="token comment"># if Bundler 2.x is not already available</span>\nbundle lock <span class="token parameter variable">--update</span>\nbundle <span class="token function">install</span></code></pre></div>'}}),"\n",l.createElement(n.h2,{id:"upgrading-precompile-hooks-for-ssr--hmr",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-precompile-hooks-for-ssr--hmr","aria-label":"upgrading precompile hooks for ssr hmr permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading Precompile Hooks for SSR + HMR"),"\n",l.createElement(n.p,null,"If your app uses server-side rendering with HMR, Shakapacker commonly runs two webpack processes during development (client HMR and server watcher). In that setup, direct-command precompile hooks are more fragile because each process can trigger the hook."),"\n",l.createElement(n.p,null,"Use a script-based hook with an explicit self-guard. This pattern is reliable across Shakapacker versions."),"\n",l.createElement(n.h3,{id:"recommended-setup",style:{position:"relative"}}
1,l.createElement(n.a,{href:"#recommended-setup","aria-label":"recommended setup permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Recommended setup"),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Create ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">bin/shakapacker-precompile-hook</code>'}}),":"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby"><span class="token comment">#!/usr/bin/env ruby</span>\n<span class="token comment"># frozen_string_literal: true</span>\n\nexit <span class="token number">0</span> <span class="token keyword">if</span> <span class="token constant">ENV</span><span class="token punctuation">[</span><span class="token string-literal"><span class="token string">"SHAKAPACKER_SKIP_PRECOMPILE_HOOK"</span></span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token string-literal"><span class="token string">"true"</span></span>\nsystem<span class="token punctuation">(</span><span class="token string-literal"><span class="token string">"bundle"</span></span><span class="token punctuation">,</span> <span class="token string-literal"><span class="token string">"exec"</span></span><span class="token punctuation">,</span> <span class="token string-literal"><span class="token string">"rake"</span></span><span class="token punctuation">,</span> <span class="token string-literal"><span class="token string">"react_on_rails:locale"</span></span><span class="token punctuation">,</span> <span class="token symbol">exception</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">)</span></code></pre></div>'}}),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Make it executable:"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token function">chmod</span> +x bin/shakapacker-precompile-hook</code></pre></div>'}}),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Configure ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/shakapacker.yml</code>'}}),":"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="yaml"><pre class="language-yaml"><code class="language-yaml"><span class="token key atrule">default</span><span class="token punctuation">:</span> <span class="token important">&default</span>\n <span class="token key atrule">precompile_hook</span><span class="token punctuation">:</span> <span class="token string">\'bin/shakapacker-precompile-hook\'</span></code></pre></div>'}}),"\n"),"\n"),"\n",l.createElement(n.h3,{id:"version-guidance",style:{position:"relative"}},l.createElement(n.a,{href:"#version-guidance","aria-label":"version guidance permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Version guidance"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Shakapacker 9.4.0+"),": Native support for ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">SHAKAPACKER_SKIP_PRECOMPILE_HOOK</code>'}})," exists."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Shakapacker 9.0-9.3"),": Prefer script-based hooks with the self-guard for reliable behavior."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"All supported versions"),": Script-based hooks are the safest choice for SSR + HMR development."),"\n"),"\n",l.createElement(n.h3,{id:"ci-recommendation",style:{position:"relative"}}
1,l.createElement(n.a,{href:"#ci-recommendation","aria-label":"ci recommendation permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"CI recommendation"),"\n",l.createElement(n.p,null,"In CI, run precompile preparation explicitly once before webpack compilation or test startup, rather than relying on hook timing in watch-like flows."),"\n",l.createElement(n.h2,{id:"upgrading-to-v17-from-v16",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-v17-from-v16","aria-label":"upgrading to v17 from v16 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to v17 (from v16)"),"\n",l.createElement(n.h3,{id:"breaking-changes",style:{position:"relative"}},l.createElement(n.a,{href:"#breaking-changes","aria-label":"breaking changes permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Breaking Changes"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Ruby 3.3+ is required.")," Upgrade Ruby before moving to React on Rails v17. React on Rails v16 remains the supported line for applications that must stay on Ruby 3.2 or older."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"React on Rails Pro already required Ruby 3.3+.")," v17 aligns the open-source gem, Pro gem, create-app validator, and CI minimum matrix on the same Ruby floor."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Four configuration options were removed.")," Three were deprecated
1in v16, while ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.server_render_method</code>'}})," was inert. All four are gone in v17. Setting any of them in ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/initializers/react_on_rails.rb</code>'}})," now raises ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">NoMethodError</code>'}})," at boot. Run ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">bin/rake react_on_rails:doctor</code>'}})," to detect any that remain in your initializer.","\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.generated_assets_dirs</code>'}})," â delete the line. Public asset paths are determined automatically from ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">public_output_path</code>'}})," in ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/shakapacker.yml</code>'}}),"."),"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.skip_display_none</code>'}})," â delete the line. It had no runtime effect."),"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.defer_generated_component_packs</code>'}})," â replaced by ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.generated_component_packs_loading_strategy</code>'}}),":","\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.defer_generated_component_packs = true</code>'}})," â ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.generated_component_packs_loading_strategy = :defer</code>'}})),"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.defer_generated_component_packs = false</code>'}})," â ",l.createElement(n.strong,null,"delete the line.")," The old option was truthy-gated â only ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">= true</code>'}})," did anything (it set ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">:defer</code>'}}),"); ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">= false</code>'}})," was a no-op that fell through to the default strategy. Deleting the line preserves that behavior. Set ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.generated_component_packs_loading_strategy = :sync</code>'}})," explicitly only if you specifically relied on synchronous (blocking) pack loading."),"\n",l.createElement(n.li,null,"The default strategy (when you don't set one) is ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">:async</code>'}})," for Pro or ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">:defer</code>'}})," for non-Pro on Shakapacker 8.2.0+, and ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">:sync</code>'}})," on older Shakapacker."),"\n"),"\n"),"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.server_render_method</code>'}})," â delete the line. The open-source gem always renders with ExecJS, so this option never selected a server render method â its validator only raised at boot for any non-blank, non-",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">"ExecJS"</code>'}})," value. Leaving it in place now raises ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">NoMethodError</code>'}})," at boot (",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">bin/rake react_on_rails:doctor</code>'}})," also flags the stale line). For a standalone Node rendering process, use React on Rails Pro's Node renderer, configured via ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactOnRailsPro.configure</code>'}}),"."),"\n"),"\n"),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"[Pro] Removed the undocumented ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactOnRailsPro::Cache.fetch_react_component</code>'}})," class API.")," Pro apps should use the supported cached helper APIs (",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">cached_react_component</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">cached_react_component_hash</code>'}}),", and related helpers) instead of calling the low-level cache class directly."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"[Pro] React Server Components now require the stable React 19.2.x RSC line.")," Pro RSC apps on v17 require ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react-on-rails-rsc >= 19.2.1 < 19.3</code>'}}),", React >= 19.2.7, and matching React DOM. Non-RSC Pro apps retain React 18 support. Set ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">REACT_ON_RAILS_PRO_DISABLE_VERSION_CHECK=1</code>'}})," only as an emergency escape hatch."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Removed the never-wired ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">RenderRequest</code>'}})," / ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">JsCodeBuilder</code>'}})," / ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">RenderingStrategy</code>'}}
1)," rendering layer.")," These internal classes were built for a strategy-pattern refactor that was never connected. Remove any application references to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactOnRails::RenderRequest</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactOnRails::JsCodeBuilder</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactOnRails::RenderingStrategy</code>'}}),", or Pro equivalents."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Removed undocumented ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactOnRails::Utils</code>'}})," helpers.")," ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactOnRails::Utils.server_rendering_is_enabled?</code>'}})," and ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactOnRails::Utils.rails_version_less_than</code>'}})," are gone. Remove any application calls."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"[Pro] Node Renderer now requires Ruby 3.3+ for the async-http transport.")," The ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react-on-rails-pro</code>'}})," gem now requires Ruby >= 3.3 (raised from >= 3.0) because ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">async-http</code>'}})," depends on Ruby 3.3 features. Upgrade Ruby before moving to this release."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"[Pro] ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.renderer_http_pool_size</code>'}})," semantics changed.")," Existing numeric values now cap concurrent async-http connections for each renderer client instead of sizing a persistent process-wide connection pool. HTTP/2 may multiplex request streams over those pooled connections. Setting ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">nil</code>'}})," keeps the default connection limit and does not make the async-http client unlimited. See the ",l.createElement(n.a,{href:"../configuration/configuration-pro.md#renderer-performance-tuning-for-streamed-rsc"},"Renderer Performance Tuning")," section."),"\n"),"\n",l.createElement(n.h3,{id:"migration-steps",style:{position:"relative"}},l.createElement(n.a,{href:"#migration-steps","aria-label":"migration steps permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Migration Steps"),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Upgrade the app to Ruby 3.3 or newer and refresh the Ruby lockfile:"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">ruby <span class="token parameter variable">-v</span>\nbundle <span class="token function">install</span></code></pre></div>'}}),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"If you scaffold apps with ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">create-react-on-rails-app</code>'}}),", make sure your shell resolves Ruby 3.3+ before running the CLI."),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Update the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_on_rails</code>'}})," gem and ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react-on-rails</code>'}})," npm package pins to the same v17 release, then install both lockfiles together:"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">bundle update react_on_rails\n<span class="token comment">
1# then run your package manager\'s install command</span>\n<span class="token function">npm</span> <span class="token function">install</span> <span class="token comment"># or: yarn install / pnpm install</span></code></pre></div>'}}),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Before booting, run the doctor task to find removed configuration options:"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">bin/rake react_on_rails:doctor</code></pre></div>'}}),"\n",l.createElement(n.p,null,"Remove or replace every option it reports in ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/initializers/react_on_rails.rb</code>'}}),". Any remaining option listed in the Breaking Changes above (",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.generated_assets_dirs</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.skip_display_none</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.defer_generated_component_packs</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.server_render_method</code>'}}),") raises ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">NoMethodError</code>'}})," at boot."),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Run RuboCop, your app's test suite, and asset build after the Ruby and package updates. The Ruby\nbaseline bump can activate cops that were previously inactive:"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">bundle <span class="token builtin class-name">exec</span> rubocop</code></pre></div>'}}),"\n"),"\n"),"\n",l.createElement(n.h2,{id:"upgrading-to-v1660-from-v165x",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-v1660-from-v165x","aria-label":"upgrading to v1660 from v165x permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to v16.6.0 (from v16.5.x)"),"\n",l.createElement(n.h3,{id:"breaking-changes-1",style:{position:"relative"}},l.createElement(n.a,{href:"#breaking-changes-1","aria-label":"breaking changes 1 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Breaking Changes"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Removed ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">immediate_hydration</code>'}})," completely.")," The ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">immediate_hydration</code>'}})," config option, helper parameter, ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">data-immediate-hydration</code>'}})," HTML attribute, and ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">redux_store</code>'}})," ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">immediate_hydration:</code>'}})," keyword argument have been removed. Immediate hydration is now always enabled for Pro users and disabled for non-Pro users, with no per-component override."),"\n"),"\n",l.createElement(n.h3,{id:"migration-steps-1",style:{position:"relative"}}
1,l.createElement(n.a,{href:"#migration-steps-1","aria-label":"migration steps 1 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Migration Steps"),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,"Remove ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.immediate_hydration</code>'}})," from ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/initializers/react_on_rails.rb</code>'}})," (or ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_on_rails_pro.rb</code>'}}),")"),"\n",l.createElement(n.li,null,"Remove any ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">immediate_hydration:</code>'}})," keyword arguments from ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_component</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_component_hash</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">stream_react_component</code>'}}),", and ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">redux_store</code>'}})," calls in your views"),"\n",l.createElement(n.li,null,"Update gem and npm package versions to 16.6.0, then run ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">bundle install</code>'}})," and your package manager's install command"),"\n"),"\n",l.createElement(n.p,null,"See the ",l.createElement(n.a,{href:"/linked-assets/4bc9a5032316a4285beb9194e1516a3b/16.6.0.md"},"v16.6.0 Release Notes")," for all changes."),"\n",l.createElement(n.h2,{id:"upgrading-to-v1650-from-v1640",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-v1650-from-v1640","aria-label":"upgrading to v1650 from v1640 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to v16.5.0 (from v16.4.0)"),"\n",l.createElement(n.h3,{id:"breaking-changes-2",style:{position:"relative"}},l.createElement(n.a,{href:"#breaking-changes-2","aria-label":"breaking changes 2 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Breaking Changes"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"[Pro] ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">RENDERER_PASSWORD</code>'}})," now required in production-like environments.")," Existing staging/production deployments using NodeRenderer without a password will fail to start after upgrading. Set ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">RENDERER_PASSWORD</code>'}})," in the environment and configure ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.renderer_password = ENV.fetch("RENDERER_PASSWORD")</code>'}})," in your Rails initializer before upgrading."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"[Pro] Minimum ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">async</code>'}})," gem version bumped to 2.29.")," The streaming helper now requires ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">async >= 2.29</code>'}})," (previously ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">>= 2.6</code>'}}),") due to the migration from ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Async::Variable</code>'}})," to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Async::Promise</code>'}}),". Run ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">bundle update async</code>'}})," if your Gemfile pins below 2.29."),"\n"),"\n",l.createElement(n.h3,{id:"changes",style:{position:"relative"}}
1,l.createElement(n.a,{href:"#changes","aria-label":"changes permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Changes"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"[Pro] Canonical env var for worker count is now ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">RENDERER_WORKERS_COUNT</code>'}}),".")," The previous ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">NODE_RENDERER_CONCURRENCY</code>'}})," is still supported as a fallback. Update deployment configs and documentation to use the new name."),"\n"),"\n",l.createElement(n.p,null,"See the ",l.createElement(n.a,{href:"/linked-assets/6abf26e5004361e59ae1a131dbfb79cc/16.5.0.md"},"v16.5.0 Release Notes")," for all changes."),"\n",l.createElement(n.h2,{id:"upgrading-to-v1640-from-v163x",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-v1640-from-v163x","aria-label":"upgrading to v1640 from v163x permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to v16.4.0 (from v16.3.x)"),"\n",l.createElement(n.p,null,"This release includes major generator improvements, development workflow enhancements, and Pro stability fixes. See the ",l.createElement(n.a,{href:"/linked-assets/fd902e74b803d8e3a9d7f812f096500a/16.4.0.md"},"v16.4.0 Release Notes")," for full details."),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Key actions required:")),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Update gem and npm package versions")," to 16.4.0"),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Pro users: remove legacy license key file")," â ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/react_on_rails_pro_license.key</code>'}})," is no longer read. Move the token to the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">REACT_ON_RAILS_PRO_LICENSE</code>'}})," environment variable"),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Pro RSC users: check ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">custom_rsc_payload_template</code>'}})," overrides")," â the template is now rendered with ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">formats: [:text]</code>'}}),". If your override is ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">.html.erb</code>'}}),", rename it to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">.text.erb</code>'}})),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Pro users upgrading from 3.x:")," See the ",l.createElement(n.a,{href:"/linked-assets/c1ca97ca44796960756f2a6cdec31f5f/updating.md"},"Pro Upgrade Guide")," for package rename steps, changed defaults, and version alignment notes"),"\n"),"\n",l.createElement(n.h2,{id:"upgrading-to-v1630-from-v162x",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-v1630-from-v162x","aria-label":"upgrading to v1630 from v162x permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to v16.3.0 (from v16.2.x)"),"\n",l.createElement(n.p,null,"This is a minor release. Update your gem and npm package versions, then run ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">bundle install</code>'}}
1)," and your package manager's install command. See the ",l.createElement(n.a,{href:"/linked-assets/93012de6b307be4c25dcdf99522b9913/16.3.0.md"},"v16.3.0 Release Notes")," for details."),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Key changes:")),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Simplified Shakapacker version handling")," â obsolete minimum version checks removed"),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"ShakaCode Trust-Based Commercial Licensing"),": A subscription is only required for production use by organizations above the free line; see ",l.createElement(n.a,{href:"https://github.com/shakacode/react_on_rails/blob/main/REACT-ON-RAILS-PRO-LICENSE.md"},"The React on Rails Pro License")),"\n"),"\n",l.createElement(n.h2,{id:"upgrading-to-v162x-from-v161x",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-v162x-from-v161x","aria-label":"upgrading to v162x from v161x permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to v16.2.x (from v16.1.x)"),"\n",l.createElement(n.p,null,"This release focuses on clear separation between open-source and Pro features. See the ",l.createElement(n.a,{href:"/linked-assets/25cf24578ad56873f1d9fc5c47ccd074/16.2.0.md"},"v16.2.x Release Notes")," for full details."),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Key actions required:")),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Remove ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.immediate_hydration</code>'}}))," from your initializer - this config option has been removed (automatic for Pro users)"),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Use exact versions")," in ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">package.json</code>'}})," - semver wildcards (",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">^</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">~</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">*</code>'}}),") now cause boot failures"),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Pro users:")," If importing Pro methods from ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react-on-rails</code>'}}),", switch to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react-on-rails-pro</code>'}})),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"RSC users:")," Move RSC configurations from ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactOnRails.configure</code>'}})," to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactOnRailsPro.configure</code>'}})),"\n"),"\n",l.createElement(n.h2,{id:"upgrading-to-v161x-from-v160x",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-v161x-from-v160x","aria-label":"upgrading to v161x from v160x permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to v16.1.x (from v16.0.x)"),"\n",l.createElement(n.p,null,"This is a minor release - update your gem and npm package versions, then run ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">bundle install</code>'}}
1)," and your package manager's install command. See the ",l.createElement(n.a,{href:"/linked-assets/77a92505f0e56bfc3a2b863ea45a96fc/16.1.0.md"},"v16.1.x Release Notes")," for new features and bug fixes."),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Deprecation:")," Remove ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.generated_assets_dirs</code>'}})," from your configuration if present. Asset paths are now automatically determined from ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">public_output_path</code>'}})," in ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/shakapacker.yml</code>'}}),"."),"\n",l.createElement(n.h2,{id:"upgrading-to-v16-from-v14v15",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-v16-from-v14v15","aria-label":"upgrading to v16 from v14v15 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to v16 (from v14/v15)"),"\n",l.createElement(n.h3,{id:"breaking-changes-3",style:{position:"relative"}},l.createElement(n.a,{href:"#breaking-changes-3","aria-label":"breaking changes 3 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Breaking Changes"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Webpacker support completely removed"),". Shakapacker >= 6.0 is now required."),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Updated runtime requirements"),":","\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"Minimum Ruby version: 3.0 (v16 minimum; v17 requires 3.3+)"),"\n",l.createElement(n.li,null,"Minimum Node.js version: 18 (the Pro Node renderer defaults to Fastify 5 and requires Node 20+; its\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">engines.node</code>'}})," floor of >= 18.19.0 applies with documented Fastify 4-compatible dependency overrides)"),"\n",l.createElement(n.li,null,"CI tests against newer Ruby and Node.js versions than these minimums; CI targets are not support floors"),"\n"),"\n"),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Install generator now validates prerequisites")," and requires at least one JavaScript package manager"),"\n"),"\n",l.createElement(n.h3,{id:"migration-steps-2",style:{position:"relative"}},l.createElement(n.a,{href:"#migration-steps-2","aria-label":"migration steps 2 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Migration Steps"),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Update Dependencies")),"\n",l.createElement(n.blockquote,null,"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Note"),": The versions below are examples. Check the ",l.createElement(n.a,{href:"https://github.com/shakacode/react_on_rails/blob/main/CHANGELOG.md"},"changelog")," for the latest stable release and substitute accordingly."),"\n"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby"><span class="token comment">
1# Gemfile</span>\ngem <span class="token string-literal"><span class="token string">"react_on_rails"</span></span><span class="token punctuation">,</span> <span class="token string-literal"><span class="token string">"16.6.0"</span></span></code></pre></div>'}}),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token comment">// package.json â use the npm equivalent of the same release</span>\n<span class="token punctuation">{</span>\n <span class="token property">"dependencies"</span><span class="token operator">:</span> <span class="token punctuation">{</span>\n <span class="token property">"react-on-rails"</span><span class="token operator">:</span> <span class="token string">"16.6.0"</span>\n <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Install Updates")),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">bundle update react_on_rails shakapacker\n<span class="token comment"># then run your package manager\'s install command</span>\n<span class="token function">npm</span> <span class="token function">install</span> <span class="token comment"># or: yarn install / pnpm install</span></code></pre></div>'}}),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Run Generator")),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">bundle <span class="token builtin class-name">exec</span> rails generate react_on_rails:install</code></pre></div>'}}),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Review and Apply Changes")),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"If your app was still on ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpacker</code>'}}),", finish that migration first"),"\n",l.createElement(n.li,null,"Check webpack configuration exports (function naming may have changed)"),"\n",l.createElement(n.li,null,"Review ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">shakapacker.yml</code>'}})," settings"),"\n",l.createElement(n.li,null,"Update ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">bin/dev</code>'}})," if needed"),"\n"),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Test Your Application")),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token comment"># Test asset compilation</span>\nbundle <span class="token builtin class-name">exec</span> rails assets:precompile\n\n<span class="token comment"># Test development server</span>\nbin/dev\n\n<span class="token comment"># Run your test suite</span>\nbundle <span class="token builtin class-name">exec</span> rspec <span class="token comment"># or your test command</span></code></pre></div>'}}),"\n"),"\n"),"\n",l.createElement(n.h3,{id:"common-upgrade-issues",style:{position:"relative"}},l.createElement(n.a,{href:"#common-upgrade-issues","aria-label":"common upgrade issues permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Common Upgrade Issues"),"\n",l.createElement(n.h4,{id:"build-fails-with-module-resolution-errors",style:{position:"relative"}}
1,l.createElement(n.a,{href:"#build-fails-with-module-resolution-errors","aria-label":"build fails with module resolution errors permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Build Fails with Module Resolution Errors"),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Symptoms:")," Webpack cannot find modules referenced in your configuration"),"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Solutions:")),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,"Clear webpack cache: ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">rm -rf node_modules/.cache</code>'}})),"\n",l.createElement(n.li,null,"Verify all ProvidePlugin modules exist"),"\n",l.createElement(n.li,null,"Check webpack alias configuration"),"\n"),"\n",l.createElement(n.p,null,"For troubleshooting build errors, see the ",l.createElement(n.a,{href:"/linked-assets/629d5fff92a46b868dccf667377c8167/troubleshooting-build-errors.md"},"build errors guide"),"."),"\n",l.createElement(n.h3,{id:"enhanced-features-in-v16",style:{position:"relative"}},l.createElement(n.a,{href:"#enhanced-features-in-v16","aria-label":"enhanced features in v16 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Enhanced Features in v16"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Enhanced error handling")," in ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_on_rails:generate_packs</code>'}})," task with detailed debugging guidance"),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Improved development tooling")," with better error messages and troubleshooting steps"),"\n",l.createElement(n.li,null,l.createElement(n.strong,null,"Better package manager detection")," with multi-strategy validation"),"\n"),"\n",l.createElement(n.h2,{id:"upgrading-to-v13",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-v13","aria-label":"upgrading to v13 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to v13"),"\n",l.createElement(n.h3,{id:"breaking-change",style:{position:"relative"}},l.createElement(n.a,{href:"#breaking-change","aria-label":"breaking change permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Breaking Change"),"\n",l.createElement(n.p,null,"Previously, the gem ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpacker</code>'}})," was a Gem dependency."),"\n",l.createElement(n.p,null,"v13 has changed slightly to switch to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">shakapacker</code>'}}),"."),"\n",l.createElement(n.p,null,"For details, see the Shakapacker guide to upgrading to ",l.createElement(n.a,{href:"https://github.com/shakacode/shakapacker/blob/master/docs/v6_upgrade.md"},"version 6")," and ",l.createElement(n.a,{href:"https://github.com/shakacode/shakapacker/blob/master/docs/v7_upgrade.md"},"version 7")),"\n",l.createElement(n.p,null,"In summary:"),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,"Change the gem reference from 'webpacker' to 'shakapacker'"),"\n",l.createElement(n.li,null,"Change the npm reference from '@rails/webpacker' to 'shakapacker'"),"\n",l.createElement(n.li,null,"Other updates, depending on what version of ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">rails/webpacker</code>'}})," that you had."),"\n"),"\n",l.createElement(n.h2,{id:"upgrading-to-v12",style:{position:"relative"}}
1,l.createElement(n.a,{href:"#upgrading-to-v12","aria-label":"upgrading to v12 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to v12"),"\n",l.createElement(n.h3,{id:"recent-versions",style:{position:"relative"}},l.createElement(n.a,{href:"#recent-versions","aria-label":"recent versions permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Recent versions"),"\n",l.createElement(n.p,null,"Make sure that you are on a relatively more recent version of Rails and Webpacker. Yes, the ",l.createElement(n.a,{href:"https://github.com/rails/webpacker"},"rails/webpacker")," gem is required!\nv12 is tested on Rails 6. It should work on Rails v5. If you're on any older version,\nand v12 doesn't work, please file an issue."),"\n",l.createElement(n.h3,{id:"removed-configuration-configsymlink_non_digested_assets_regex",style:{position:"relative"}},l.createElement(n.a,{href:"#removed-configuration-configsymlink_non_digested_assets_regex","aria-label":"removed configuration configsymlink_non_digested_assets_regex permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Removed Configuration config.symlink_non_digested_assets_regex"),"\n",l.createElement(n.p,null,"Remove ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.symlink_non_digested_assets_regex</code>'}})," from your ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/initializers/react_on_rails.rb</code>'}}),".\nIf you still need that feature, please file an issue."),"\n",l.createElement(n.h3,{id:"i18n-default-format-changed-to-json",style:{position:"relative"}},l.createElement(n.a,{href:"#i18n-default-format-changed-to-json","aria-label":"i18n default format changed to json permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"i18n default format changed to JSON"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"If you're using the internationalization helper, then set ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:"<code class=\"language-text\">config.i18n_output_format = 'js'</code>"}}),". You can\nlater update to the default JSON format as you will need to update your usage of that file. A JSON\nformat is more efficient."),"\n"),"\n",l.createElement(n.h3,{id:"updated-api-for-reactonrailsregister",style:{position:"relative"}}
1,l.createElement(n.a,{href:"#updated-api-for-reactonrailsregister","aria-label":"updated api for reactonrailsregister permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Updated API for ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactOnRails.register()</code>'}})),"\n",l.createElement(n.p,null,"In order to solve the issues regarding React Hooks compatibility, the number of parameters\nfor functions is used to determine if you have a Render-Function that will get invoked to\nreturn a React component, or you are registering a React component defined by a function.\nPlease see ",l.createElement(n.a,{href:"/linked-assets/437539654674ca3b3c8e166e0056e147/render-functions-and-railscontext.md"},"Render-Functions and the Rails Context")," for\nmore information on what a Render-Function is."),"\n",l.createElement(n.h5,{id:"update-required-for-registered-functions-taking-exactly-2-params",style:{position:"relative"}},l.createElement(n.a,{href:"#update-required-for-registered-functions-taking-exactly-2-params","aria-label":"update required for registered functions taking exactly 2 params permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Update required for registered functions taking exactly 2 params."),"\n",l.createElement(n.p,null,"Registered Objects are of the following type:"),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Function that takes only zero or one params and returns a React Element"),", often JSX. If the function takes zero or one params, there is ",l.createElement(n.strong,null,"no migration needed")," for that function."),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator"><</span>Component <span class="token punctuation">{</span><span class="token operator">...</span>props<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">;</span></code></pre></div>'}}),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,l.createElement(n.strong,null,"Function that takes only zero or one params and returns an Object (",l.createElement(n.em,null,"not a React Element"),")"),". If the function takes zero or one params, ",l.createElement(n.strong,null,"you need to add one or two unused params so you have exactly 2 params")," and then that function will be treated as a render function and it can return an Object rather than a React element. If you don't do this, you'll see this obscure error message:"),"\n"),"\n"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text"> [SERVER] message: Objects are not valid as a React child (found: object with keys {renderedHtml}). If you meant to render a collection of children, use an array instead.\n in YourComponentRenderFunction</code></pre></div>'}}),"\n",l.createElement(n.p,null,"So look in ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">YourComponentRenderFunction</code>'}})," and do this change"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span>\n <span class="token literal-property property">renderedHTML</span><span class="token operator">:</span> <span class="token function">getRenderedHTML</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>\n<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",l.createElement(n.p,null,"To have exactly 2 arguments:"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">props<span class="token punctuation">,</span> _railsContext</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span>\n <span class="token literal-property property">renderedHTML</span><span class="token operator">:</span> <span class="token function">getRenderedHTML</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>\n<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",l.createElement(n.ol,{start:"3"},"\n",l.createElement(n.li,null,"Function that takes ",l.createElement(n.strong,null,"2 params")," and returns ",l.createElement(n.strong,null,"a React function or class component"),". ",l.createElement(n.em,null,"Migration is needed as the older syntax returned a React Element."),"\nA function component is a function that takes zero or one params and returns a React Element, like JSX. The correct syntax\nlooks like:","\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">props<span class="token punctuation">,</span> railsContext</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator"><</span>Component <span class="token punctuation">{</span><span class="token operator">...</span><span class="token punctuation">{</span> <span class="token operator">...</span>props<span class="token punctuation">,</span> railsContext <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">;</span></code></pre></div>'}}
1),"\n","Note, you cannot return a React Element (JSX). See below for the migration steps. If your function that took ",l.createElement(n.strong,null,"two params returned\nan Object"),", then no migration is required."),"\n",l.createElement(n.li,null,"Function that takes ",l.createElement(n.strong,null,"3 params")," and uses the 3rd param, ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">domNodeId</code>'}}),", to call ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ReactDOM.hydrate</code>'}}),". If the function takes 3 params, there is ",l.createElement(n.strong,null,"no migration needed")," for that function."),"\n",l.createElement(n.li,null,"ES6 or ES5 class. There is ",l.createElement(n.strong,null,"no migration needed"),"."),"\n"),"\n",l.createElement(n.p,null,"Previously, with case number 2, you could return a React Element."),"\n",l.createElement(n.p,null,"The fix is simple. Here is an example of the change you'll do:"),"\n",l.createElement(n.img,{src:"https://user-images.githubusercontent.com/1118459/86927351-eff79e80-c0ce-11ea-9172-d6855c45e2bb.png",alt:"2020-07-07_09-43-51 (1)"}),"\n",l.createElement(n.h5,{id:"broken-as-this-function-takes-two-params-and-it-returns-a-react-element-from-a-jsx-literal",style:{position:"relative"}},l.createElement(n.a,{href:"#broken-as-this-function-takes-two-params-and-it-returns-a-react-element-from-a-jsx-literal","aria-label":"broken as this function takes two params and it returns a react element from a jsx literal permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Broken, as this function takes two params and it returns a React Element from a JSX Literal"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">props<span class="token punctuation">,</span> _railsContext</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator"><</span>Component <span class="token punctuation">{</span><span class="token operator">...</span>props<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",l.createElement(n.p,null,"If you make this mistake, you'll get this warning\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: <Fragment />. Did you accidentally export a JSX literal instead of a component?</code>'}})),"\n",l.createElement(n.p,null,"And this error:\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react-dom.development.js:23965 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.</code>'}})),"\n",l.createElement(n.p,null,"In this example, you need to wrap the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text"><Component {...props} /></code>'}})," in a function call like this which\nresults in the return value being a React function component."),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">props<span class="token punctuation">,</span> _railsContext</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator"><</span>Component <span class="token punctuation">{</span><span class="token operator">...</span>props<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",l.createElement(n.p,null,"If you have a pure component, taking one or zero parameters, and you have an unnecessary function\nwrapper such that you're returning a function rather than a React Element, then:"),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,"You won't see anything render."),"\n",l.createElement(n.li,null,"You will see this warning in development mode: ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.</code>'}})),"\n"),"\n",l.createElement(n.hr),"\n",l.createElement(n.h2,{id:"upgrading-railswebpacker-from-v3-to-v4",style:{position:"relative"}}
1,l.createElement(n.a,{href:"#upgrading-railswebpacker-from-v3-to-v4","aria-label":"upgrading railswebpacker from v3 to v4 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading rails/webpacker from v3 to v4"),"\n",l.createElement(n.h3,{id:"custom-webpack-build-file",style:{position:"relative"}},l.createElement(n.a,{href:"#custom-webpack-build-file","aria-label":"custom webpack build file permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Custom Webpack build file"),"\n",l.createElement(n.p,null,"The default value for ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">extract_css</code>'}})," is ",l.createElement(n.strong,null,"false")," in ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/webpack.yml</code>'}}),". Custom Webpack builds should set this value to true, or else no CSS link tags are generated. You have a custom Webpack build if you are not using ",l.createElement(n.a,{href:"https://github.com/rails/webpacker"},"rails/webpacker")," to set up your Webpack configuration."),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="yml"><pre class="language-yml"><code class="language-yml"><span class="token key atrule">default</span><span class="token punctuation">:</span> <span class="token important">&default</span> <span class="token comment"># other stuff</span>\n <span class="token key atrule">extract_css</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>\n <span class="token comment"># by default, extract and emit a css file. The default is false</span></code></pre></div>'}}),"\n",l.createElement(n.h2,{id:"upgrading-to-version-11",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-version-11","aria-label":"upgrading to version 11 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to version 11"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"Remove ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">server_render_method</code>'}})," from config/initializers/react_on_rails.rb. Alternate server rendering methods are part of React on Rails Pro. If you want to use a custom renderer, contact ",l.createElement(n.a,{href:"mailto:[email protected]"},"[email protected]"),". We have a custom node rendering solution in production for egghead.io."),"\n",l.createElement(n.li,null,'Remove your usage of ENV["TRACE_REACT_ON_RAILS"] usage. You can get all tracing with either specifying ',l.createElement(n.strong,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">trace</code>'}}
1))," at your component or in your config/initializers/react_on_rails.rb file."),"\n",l.createElement(n.li,null,"ReactOnRails::Utils.server_bundle_file_name and ReactOnRails::Utils.bundle_file_name were removed. React on Rails Pro contains upgrades to enable component and other types caching with React on Rails."),"\n"),"\n",l.createElement(n.h2,{id:"upgrading-to-version-10",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-version-10","aria-label":"upgrading to version 10 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to version 10"),"\n",l.createElement(n.p,null,"Pretty simple:"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"Follow the steps to migrate to version 9 (except installing 10.x instead of 9.x)"),"\n",l.createElement(n.li,null,"If you have ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_component</code>'}})," returning hashes, then switch to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_component_hash</code>'}})," instead"),"\n"),"\n",l.createElement(n.h2,{id:"upgrading-to-version-9",style:{position:"relative"}},l.createElement(n.a,{href:"#upgrading-to-version-9","aria-label":"upgrading to version 9 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Upgrading to version 9"),"\n",l.createElement(n.h3,{id:"why-webpacker",style:{position:"relative"}},l.createElement(n.a,{href:"#why-webpacker","aria-label":"why webpacker permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Why Webpacker?"),"\n",l.createElement(n.p,null,"Webpacker provides areas of value:"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"View helpers that support bypassing the asset pipeline, which allows you to avoid double minification and enable source maps in production. This is 100% a best practice, as source maps in production greatly increases the value of services such as HoneyBadger or Sentry."),"\n",l.createElement(n.li,null,"A default Webpack config so that you only need to do minimal modifications and customizations. However, if you're doing server rendering, you may not want to give up control. Since Webpacker's default Webpack config is changing often, we at Shakacode can give you definitive advice on Webpack configuration best practices. In general, if you're happy with doing your own Webpack configuration, then we suggest using the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">client</code>'}})," strategy discussed below. Most corporate projects will prefer having more control than direct dependence on webpacker easily allows."),"\n"),"\n",l.createElement(n.h3,{id:"integrating-webpacker",style:{position:"relative"}}
1,l.createElement(n.a,{href:"#integrating-webpacker","aria-label":"integrating webpacker permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Integrating Webpacker"),"\n",l.createElement(n.p,null,"Reason for doing this: This enables your Webpack bundles to bypass the Rails asset pipeline and its extra minification, enabling you to use source-maps in production, while still maintaining total control over everything in the client directory."),"\n",l.createElement(n.h4,{id:"from-version-7-or-lower",style:{position:"relative"}},l.createElement(n.a,{href:"#from-version-7-or-lower","aria-label":"from version 7 or lower permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"From version 7 or lower"),"\n",l.createElement(n.h5,{id:"while-keeping-your-client-directory",style:{position:"relative"}},l.createElement(n.a,{href:"#while-keeping-your-client-directory","aria-label":"while keeping your client directory permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"...while keeping your ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">client</code>'}})," directory"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">.gitignore</code>'}}),": add ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">/public/webpack/*</code>'}}),"."),"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Gemfile</code>'}}),": bump ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_on_rails</code>'}})," and add ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpacker</code>'}}),"."),"\n",l.createElement(n.li,null,"layout views: anything bundled by Webpack will need to be requested by a ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">javascript_pack_tag</code>'}})," or ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">stylesheet_pack_tag</code>'}}),"."),"\n",l.createElement(n.li,null,"Search your codebase for javascript_include_tag. Use the"),"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/initializers/assets.rb</code>'}}),": we no longer need to modify ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Rails.application.config.assets.paths</code>'}})," or append anything to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Rails.application.config.assets.precompile</code>'}}),"."),"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">
1config/initializers/react_on_rails.rb</code>'}}),":","\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"Delete ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.generated_assets_dir</code>'}}),". Webpacker's config now supplies this information."),"\n",l.createElement(n.li,null,"Replace ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.npm_build_(test|production)_command</code>'}})," with ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.build_(test|production)_command</code>'}}),"."),"\n"),"\n"),"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/webpacker.yml</code>'}}),": start with our ",l.createElement(n.a,{href:"https://github.com/shakacode/react-on-rails-v9-rc-generator/blob/master/config/webpacker.yml"},"example config")," (feel free to modify it as needed). I recommend setting dev_server.hmr to false however since HMR is currently broken."),"\n",l.createElement(n.li,null,l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">client/package.json</code>'}}),": bump ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_on_rails</code>'}})," (I recommend bumping ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpack</code>'}})," as well). You'll also need ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">js-yaml</code>'}})," if you're not already using ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">eslint</code>'}})," and ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpack-manifest-plugin</code>'}})," regardless."),"\n"),"\n",l.createElement(n.h6,null,"Client Webpack config"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"You'll need the following code to read data from the webpacker
1config:"),"\n"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'path\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token keyword">const</span> ManifestPlugin <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'webpack-manifest-plugin\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// we\'ll use this later</span>\n\n<span class="token keyword">const</span> webpackConfigLoader <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'react-on-rails/webpackConfigLoader\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token keyword">const</span> configPath <span class="token operator">=</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">\'..\'</span><span class="token punctuation">,</span> <span class="token string">\'config\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token keyword">const</span> <span class="token punctuation">{</span> output <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">webpackConfigLoader</span><span class="token punctuation">(</span>configPath<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"That output variable will be used for Webpack's ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">output</code>'}})," rules:"),"\n"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"> <span class="token literal-property property">output</span><span class="token operator">:</span> <span class="token punctuation">{</span>\n <span class="token literal-property property">filename</span><span class="token operator">:</span> <span class="token string">\'[name]-[chunkhash].js\'</span><span class="token punctuation">,</span> <span class="token comment">// [chunkhash] because we\'ve got to do our own cache-busting now</span>\n <span class="token literal-property property">path</span><span class="token operator">:</span> output<span class="token punctuation">.</span>path<span class="token punctuation">,</span>\n <span class="token literal-property property">publicPath</span><span class="token operator">:</span> output<span class="token punctuation">.</span>publicPath<span class="token punctuation">,</span>\n <span class="token punctuation">}</span><span class="token punctuation">,</span></code></pre></div>'}}),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"...as well as for the output of plugins like ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpack-manifest-plugin</code>'}}),":"),"\n"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript">
1\n <span class="token keyword">new</span> <span class="token class-name">ManifestPlugin</span><span class="token punctuation">(</span><span class="token punctuation">{</span>\n <span class="token literal-property property">publicPath</span><span class="token operator">:</span> output<span class="token punctuation">.</span>publicPath<span class="token punctuation">,</span>\n <span class="token literal-property property">writeToFileEmit</span><span class="token operator">:</span> <span class="token boolean">true</span>\n <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></code></pre></div>'}}),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"If you're using referencing files or images with ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">url-loader</code>'}})," & ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">file-loader</code>'}}),", their publicpaths will have to change as well: ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:"<code class=\"language-text\">publicPath: '/webpack/',</code>"}})),"\n",l.createElement(n.li,null,"If you're using ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">css-loader</code>'}}),", ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpack.optimize.CommonsChunkPlugin</code>'}}),", or ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">extract-text-webpack-plugin</code>'}}),", they will also need cache-busting!"),"\n"),"\n",l.createElement(n.p,null,"...and you're finally done!"),"\n",l.createElement(n.h5,{id:"while-replacing-your-client-directory",style:{position:"relative"}},l.createElement(n.a,{href:"#while-replacing-your-client-directory","aria-label":"while replacing your client directory permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"...while replacing your ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">client</code>'}})," directory"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"Make the same changes to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/initializers/react_on_rails.rb as described above</code>'}})),"\n",l.createElement(n.li,null,"Upgrade RoR & add Webpacker in the Gemfile"),"\n",l.createElement(n.li,null,"Upgrade RoR in the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">client/package.json</code>'}})),"\n",l.createElement(n.li,null,"Run ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">bundle</code>'}})),"\n",l.createElement(n.li,null,"Run ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">rails webpacker:install</code>'}})),"\n",l.createElement(n.li,null,"Run ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">rails webpacker:install:react</code>'}})),"\n",l.createElement(n.li,null,"Run ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">rails g react_on_rails:install</code>'}})),"\n",l.createElement(n.li,null,"Move your entry point files to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">app/javascript/packs</code>'}})),"\n",l.createElement(n.li,null,"Either:","\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"Move all your source code to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">app/javascript/bundles</code>'}}),", move your linter configs to the root directory, and then delete the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">client</code>'}})," directory"),"\n",l.createElement(n.li,null,"or just delete the Webpack config and remove Webpack, its loaders, and plugins from your ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">client/package.json</code>'}}),"."),"\n"),"\n"),"\n"),"\n",l.createElement(n.p,null,"...and you're done."),"\n",l.createElement(n.h4,{id:"from-version-8",style:{position:"relative"}}
1,l.createElement(n.a,{href:"#from-version-8","aria-label":"from version 8 permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"From version 8"),"\n",l.createElement(n.p,null,"For an example of upgrading, see ",l.createElement(n.a,{href:"https://github.com/shakacode/react-webpack-rails-tutorial/pull/416"},"react-webpack-rails-tutorial/pull/416"),"."),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Breaking Configuration Changes"),"\n",l.createElement(n.ol,null,"\n",l.createElement(n.li,null,"Added ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.node_modules_location</code>'}})," which defaults to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">""</code>'}})," if Webpacker is installed. You may want to set this to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:"<code class=\"language-text\">'client'</code>"}})," in ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/initializers/react_on_rails.rb</code>'}})," to keep your ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">node_modules</code>'}})," inside the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">/client</code>'}})," directory."),"\n",l.createElement(n.li,null,"Renamed","\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"config.npm_build_test_command ==> config.build_test_command"),"\n",l.createElement(n.li,null,"config.npm_build_production_command ==> config.build_production_command"),"\n"),"\n"),"\n"),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Update the gemfile. Switch over to using the webpacker gem."),"\n"),"\n"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="rb"><pre class="language-rb"><code class="language-rb">gem <span class="token string-literal"><span class="token string">"webpacker"</span></span></code></pre></div>'}}),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Update for the renaming in the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">WebpackConfigLoader</code>'}})," in your Webpack configuration.\nYou will need to rename the following object properties:"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"webpackOutputPath ==> output.path"),"\n",l.createElement(n.li,null,"webpackPublicOutputDir ==> output.publicPath"),"\n",l.createElement(n.li,null,"hotReloadingUrl ==> output.publicPathWithHost"),"\n",l.createElement(n.li,null,"hotReloadingHostname ==> settings.dev_server.host"),"\n",l.createElement(n.li,null,"hotReloadingPort ==> settings.dev_server.port"),"\n",l.createElement(n.li,null,"hmr ==> settings.dev_server.hmr"),"\n",l.createElement(n.li,null,"manifest ==> Remove this one. We use the default for Webpack of manifest.json"),"\n",l.createElement(n.li,null,"env ==> Use ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:"<code class=\"language-text\">const { env } = require('process');</code>"}})),"\n",l.createElement(n.li,null,"devBuild ==> Use ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:"<code class=\"language-text\">const devBuild = process.env.NODE_ENV !== 'production';</code>"}})),"\n"),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Edit your Webpack.config files:"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Change your Webpack output to be like this. ",l.createElement(n.strong,null,"Be sure to have the hash or chunkhash in the filename,")," unless the bundle is server side.:"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> webpackConfigLoader <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'react-on-rails/webpackConfigLoader\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token keyword">const</span> configPath <span class="token operator">=</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">\'..\'</span><span class="token punctuation">,</span> <span class="token string">\'config\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token keyword">const</span> <span class="token punctuation">{</span> output<span class="token punctuation">,</span> settings <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">webpackConfigLoader</span><span class="token punctuation">(</span>configPath<span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token keyword">const</span> hmr <span class="token operator">=</span> settings<span class="token punctuation">.</span>dev_server<span class="token punctuation">.</span>hmr<span class="token punctuation">;</span>\n<span class="token keyword">const</span> devBuild <span class="token operator">=</span> process<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">NODE_ENV</span> <span class="token operator">!==</span> <span class="token string">\'production\'</span><span class="token punctuation">;</span>\n\n<span class="token literal-property property">output</span><span class="token operator">:</span> <span class="token punctuation">{</span>\n <span class="token literal-property property">filename</span><span class="token operator">:</span> isHMR <span class="token operator">?</span> <span class="token string">\'[name]-[hash].js\'</span> <span class="token operator">:</span> <span class="token string">\'[name]-[chunkhash].js\'</span><span class="token punctuation">,</span>\n <span class="token literal-property property">chunkFilename</span><span class="token operator">:</span> <span class="token string">\'[name]-[chunkhash].chunk.js\'</span><span class="token punctuation">,</span>\n\n <span class="token literal-property property">publicPath</span><span class="token operator">:</span> output<span class="token punctuation">.</span>publicPath<span class="token punctuation">,</span>\n <span class="token literal-property property">path</span><span class="token operator">:</span> output<span class="token punctuation">.</span>path<span class="token punctuation">,</span>\n<span class="token punctuation">}</span><span class="token punctuation">,</span></code></pre></div>'}}),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Change your ManifestPlugin definition to something like the following"),"\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">new</span> <span class="token class-name">ManifestPlugin</span><span class="token punctuation">(</span><span class="token punctuation">{</span>\n <span class="token literal-property property">publicPath</span><span class="token operator">:</span> output<span class="token punctuation">.</span>publicPath<span class="token punctuation">,</span>\n <span class="token literal-property property">writeToFileEmit</span><span class="token operator">:</span> <span class="token boolean">true</span>\n <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span>\n</code></pre></div>'}}),"\n"),"\n"),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Find your ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpacker_lite.yml</code>'}})," and rename it to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpacker.yml</code>'}})),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"Consider copying a default webpacker.yml setup such as ",l.createElement(n.a,{href:"https://github.com/shakacode/react-on-rails-v9-rc-generator/blob/master/config/webpacker.yml"},"https://github.com/shakacode/react-on-rails-v9-rc-generator/blob/master/config/webpacker.yml")),"\n",l.createElement(n.li,null,"If you are not using the webpacker Webpack setup, be sure to put in ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">compile: false</code>'}})," in the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">default</code>'}})," section."),"\n",l.createElement(n.li,null,"Alternately, if you are updating from webpacker_lite, you can manually change these:"),"\n",l.createElement(n.li,null,"Add a default setting","\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="yaml"><pre class="language-yaml"><code class="language-yaml"><span class="token key atrule">cache_manifest</span><span class="token punctuation">:</span> <span class="token boolean important">
1false</span></code></pre></div>'}}),"\n"),"\n",l.createElement(n.li,null,"For production, set:","\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="yaml"><pre class="language-yaml"><code class="language-yaml"><span class="token key atrule">cache_manifest</span><span class="token punctuation">:</span> <span class="token boolean important">true</span></code></pre></div>'}}),"\n"),"\n",l.createElement(n.li,null,"Add a section like this under your development env:","\n",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="yaml"><pre class="language-yaml"><code class="language-yaml"><span class="token key atrule">dev_server</span><span class="token punctuation">:</span>\n <span class="token key atrule">host</span><span class="token punctuation">:</span> localhost\n <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">3035</span>\n <span class="token key atrule">hmr</span><span class="token punctuation">:</span> <span class="token boolean important">false</span></code></pre></div>'}}),"\n","Set hmr to your preference."),"\n",l.createElement(n.li,null,"See the example ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">react_on_rails/spec/dummy/config/webpacker.yml</code>'}}),"."),"\n",l.createElement(n.li,null,"Remove keys ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">hot_reloading_host</code>'}})," and ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">hot_reloading_enabled_by_default</code>'}}),". These are replaced by the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">dev_server</code>'}})," key."),"\n",l.createElement(n.li,null,"Rename ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpack_public_output_dir</code>'}})," to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">public_output_path</code>'}}),"."),"\n"),"\n"),"\n",l.createElement(n.li,null,"\n",l.createElement(n.p,null,"Edit your Procfile.dev"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"Remove the env value WEBPACKER_DEV_SERVER as it's not used"),"\n",l.createElement(n.li,null,"For hot loading:","\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"Set the ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">hmr</code>'}})," key in your ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">webpacker.yml</code>'}})," to ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">true</code>'}}),"."),"\n"),"\n"),"\n"),"\n"),"\n"),"\n",l.createElement(n.h3,{id:"without-integrating-webpacker",style:{position:"relative"}},l.createElement(n.a,{href:"#without-integrating-webpacker","aria-label":"without integrating webpacker permalink",className:"anchor before"},l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Without integrating webpacker"),"\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"Bump your ReactOnRails versions in ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Gemfile</code>'}})," & ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">package.json</code>'}})),"\n",l.createElement(n.li,null,"In ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">/config/initializers/react_on_rails.rb</code>'}}),":","\n",l.createElement(n.ul,null,"\n",l.createElement(n.li,null,"Rename ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.npm_build_test_command</code>'}})," ==> ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.build_test_command</code>'}})),"\n",l.createElement(n.li,null,"Rename ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.npm_build_production_command</code>'}})," ==> ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.build_production_command</code>'}})),"\n",l.createElement(n.li,null,"Add ",l.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config.node_modules_location = "client"</code>'}})),"\n"),"\n"),"\n"),"\n",l.createElement(n.p,null,"...and you're done."))}
1var r=function(e){void 0===e&&(e={});const{wrapper:n}=Object.assign({},(0,t.R)(),e.components);return n?l.createElement(n,e,l.createElement(s,e)):s(e)},o=a(63679),c=a(95197),i=a(47388),p=a(23690),u=a(14487);const d=o.default.p.withConfig({displayName:"doc-article__RedirectFallback",componentId:"sc-tic2w5-0"})(["padding:2rem;"]),g=e=>{let{data:n,location:a,children:t}=e;const{headings:s}=n.article.childMdx,r=(0,c.X9)(a.pathname),[o,p]=l.useState(null),g=a.pathname.split("/"),m=g.indexOf("docs"),h=-1===m?a.pathname.length:g.slice(0,m+1).join("/").length,_=a.pathname.slice(0,h),v=a.pathname.slice(h+1).replace(/\/$/,"").split("/").filter((e=>""!==e)),E=v.length>1?v.slice(0,-1).join("/"):"";l.useEffect((()=>{if(!r)return;const{hash:e}=window.location;p(e);const n=""+r+e;window.location.href!==n&&window.location.replace(n)}),[r]);const y=null===r||null===o?null:""+r+o;return l.createElement(l.Fragment,null,null!==y?l.createElement(d,{role:"status","aria-live":"polite"},"Redirecting..."," ",l.createElement("a",{href:y,target:"_blank",rel:"noopener noreferrer"},"Click here if not redirected.")):l.createElement(i.A,{main:l.createElement(u.A,{body:t,headings:s,transformUrl:e=>{if(e.startsWith("http")||e.startsWith("#"))return e;const n=e.replace(/\.md$/,"/");if(n.startsWith("./"))return _+(""===E?"":"/"+E)+n.slice(1);if(n.startsWith("../")){if(""===E)return""+_+n.slice(2);const e=E.split("/").slice(0,-1).join("/");return _+(""===e?"":"/"+e)+n.slice(2)}return _+"/"+(""===E?"":E+"/")+n}})}))};function m(e){return l.createElement(g,e,l.createElement(r,e))}const h=e=>{let{data:n,location:a,pageContext:t}=e;const{headings:s}=n.article.childMdx,{siteUrl:r}=n.site.siteMetadata,{repoDisplayName:o}=t,i=s.find((e=>1===e.depth)),u=(0,c.X9)(a.pathname)||""+r.replace(/\/+$/,"")+a.pathname;return l.createElement(p.A,{title:i?i.value:o,description:i?i.value:o+" documentation",isArticle:!0,canonical:u,pathname:a.pathname})}}}]); 2//# sourceMappingURL=component---src-template-doc-article-tsx-content-file-path-cache-gatsby-source-git-react-on-rails-docs-oss-upgrading-upgrading-react-on-rails-md-40b925ec359c8708a2ac.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.