<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Patrick Kilgore</title>
    <description>The latest articles on Forem by Patrick Kilgore (@pckilgore).</description>
    <link>https://forem.com/pckilgore</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F279590%2Fc47a0486-4709-4acb-863f-511d9681dda9.jpeg</url>
      <title>Forem: Patrick Kilgore</title>
      <link>https://forem.com/pckilgore</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/pckilgore"/>
    <language>en</language>
    <item>
      <title>Easy Dune (OCaml): Running a Script</title>
      <dc:creator>Patrick Kilgore</dc:creator>
      <pubDate>Sun, 07 Aug 2022 21:06:00 +0000</pubDate>
      <link>https://forem.com/pckilgore/unofficial-dune-ocaml-how-to-running-a-script-2fgh</link>
      <guid>https://forem.com/pckilgore/unofficial-dune-ocaml-how-to-running-a-script-2fgh</guid>
      <description>&lt;p&gt;There's a lot to dune, the OCaml build system.  It can probably do what you want, but the documentation—while thorough—never bothers to explain how to complete common tasks in a way a busy developer would find helpful.&lt;/p&gt;

&lt;p&gt;This is a "how to" to run a script with dune. By the end, you'll be able to trigger the execution of an arbitrary program with dune to complete a useful task for your code-base. Think &lt;code&gt;"scripts"&lt;/code&gt; in a &lt;code&gt;package.json&lt;/code&gt;, or a &lt;code&gt;.PHONY&lt;/code&gt; target in a &lt;code&gt;Makefile&lt;/code&gt;. For example, you might run a code-generation CLI like &lt;a href="https://tailwindcss.com"&gt;tailwindcss&lt;/a&gt;, or push build artifacts to S3 with an &lt;code&gt;aws&lt;/code&gt; CLI invocation. We'll refer to these kinds of things as "scripts", as we might in a node/JavaScript project.&lt;/p&gt;

&lt;h4&gt;
  
  
  Assumptions
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You know your way around a terminal and basic POSIX shell commands &lt;/li&gt;
&lt;li&gt;You've got a working installation of dune version 3:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;dune &lt;span class="nt"&gt;--version&lt;/span&gt;
3.4.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  From Scratch
&lt;/h2&gt;

&lt;p&gt;If you've already got a dune project, locate the &lt;code&gt;dune&lt;/code&gt; file in which you'd like to define the command, change directories to that folder, and skip ahead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Your &lt;code&gt;dune&lt;/code&gt; File
&lt;/h3&gt;

&lt;p&gt;Scripts are defined in a file named &lt;code&gt;dune&lt;/code&gt; at the root of your project (or library, or executable). Dune has a suite of &lt;code&gt;init&lt;/code&gt; commands to help create this file, but these create a lot of unnecessary noise too, so let's make the minimum setup manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;run_task &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;run_task
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;dune
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"(lang dune 3.3)"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dune-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point you should be able to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;dune build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without seeing an error, and a new folder &lt;code&gt;_build&lt;/code&gt; appearing, which confirms we're ready to go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
├── _build
│   ├── default
│   └── log
├── dune
└── dune-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuring Dune with S-Expressions
&lt;/h3&gt;

&lt;p&gt;Let's quickly look at one of the commands above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"(lang dune 3.3)"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dune-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might be wondering what &lt;code&gt;lang dune 3.3&lt;/code&gt; means and why it's in parentheses. It's called an &lt;a href="https://en.wikipedia.org/wiki/S-expression"&gt;S-Expression&lt;/a&gt;, and like &lt;code&gt;JSON&lt;/code&gt;, &lt;code&gt;YAML&lt;/code&gt; or &lt;code&gt;TOML&lt;/code&gt; is a language that can be used for, among other things, configuration files.  Unlike the latter few formats, S-Expressions are not frequently seen outside OCaml, but they are a common way in OCaml to serialize data, much in the way &lt;code&gt;JSON&lt;/code&gt; is a common way to serialize data in JavaScript.&lt;/p&gt;

&lt;p&gt;You might find it a bizarre choice for a programming tool and language hoping to attract new users (I do).  But regardless, it's how we'll "program" &lt;code&gt;dune&lt;/code&gt; to do what we want.&lt;/p&gt;

&lt;p&gt;Fortunately, you don't need to know much about s-expressions to do what we need here. For now, you can think of them as named, nested arrays:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(key value value (subkey value))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's an imaginary example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(package (name my-package)(version 1.0))
(dependencies lib-1 lib-2 lib-3 (testing-only tool-a tool-b)(development-only lib-a))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trick is knowing which &lt;code&gt;key&lt;/code&gt;s are significant to &lt;code&gt;dune&lt;/code&gt;, and how &lt;code&gt;dune&lt;/code&gt; responds to different values for those keys, similar to how you need to know in a &lt;code&gt;npm&lt;/code&gt; project that the &lt;code&gt;package.json&lt;/code&gt; key &lt;code&gt;"files"&lt;/code&gt; requires an array of file patterns as the value.&lt;/p&gt;

&lt;p&gt;They can be a pain to read without adding white space, so I suggest adding whatever white space makes it easiest for you.  The below is equivalent to the above, made a &lt;em&gt;little&lt;/em&gt; easier to read with strategic white space:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(package 
  (name my-package)
  (version 1.0))

(dependencies 
    lib-1 
    lib-2
    lib-3 
    (testing-only tool-a tool-b)
    (development-only lib-a))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding a Script: Rules &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;You define a script in a dune project as a &lt;a href="https://dune.readthedocs.io/en/stable/dune-files.html#rule"&gt;&lt;strong&gt;rule&lt;/strong&gt;&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  A Simple Rule
&lt;/h3&gt;

&lt;p&gt;For now, copy this basic "hello world" rule into your &lt;code&gt;dune&lt;/code&gt; file and save it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(rule
  (alias helloworld)
  (deps (universe))
  (action (run echo "Hello World!")))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;If you already have entries in your dune file, add this below everything else, un-nested.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You should now be able to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;dune build @helloworld
Hello World!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome! We're 90% of the way there for invoking simple scripts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Simple Rules
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Aliases
&lt;/h4&gt;

&lt;p&gt;Each rule can have an alias, which you invoke with the &lt;code&gt;build&lt;/code&gt; command by prefixing it with an &lt;code&gt;@&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that you can alias a lot of things in &lt;code&gt;dune&lt;/code&gt;, for example, a set of dependencies. Be careful when referencing the docs!&lt;/p&gt;

&lt;h4&gt;
  
  
  Action
&lt;/h4&gt;

&lt;p&gt;An action is the command &lt;code&gt;dune&lt;/code&gt; runs to satisfy the rule. The basic syntax is demonstrated above, but there's an internal language that can get &lt;a href="https://dune.readthedocs.io/en/stable/concepts.html?highlight=actions#user-actions-1"&gt;quite complex&lt;/a&gt;. And you can always use the simple syntax to invoke a small program to perform any more complicated build task!  For example, if you really like S-Expressions you can write some crazy shell scripts with the &lt;a href="https://github.com/janestreet/shexp"&gt;shexp&lt;/a&gt; library.&lt;/p&gt;

&lt;p&gt;Other common actions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;(action (system &amp;lt;cmd&amp;gt;))&lt;/code&gt;: executes &lt;code&gt;&amp;lt;cmd&amp;gt;&lt;/code&gt; with &lt;code&gt;sh&lt;/code&gt; on unix and &lt;code&gt;cmd&lt;/code&gt; on windows.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(action (bash &amp;lt;cmd&amp;gt;))&lt;/code&gt;: executes &lt;code&gt;&amp;lt;cmd&amp;gt;&lt;/code&gt; in a bash shell&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Dependencies
&lt;/h4&gt;

&lt;p&gt;Unlike scripts in the &lt;code&gt;npm&lt;/code&gt; ecosystem, &lt;code&gt;rules&lt;/code&gt; in &lt;code&gt;dune&lt;/code&gt; have dependencies, which are tracked by &lt;code&gt;dune&lt;/code&gt; to avoid unnecessary work.&lt;/p&gt;

&lt;p&gt;To illustrate this, remove this line from the example "hello world" above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt; (rule
   (alias helloworld)
&lt;span class="gd"&gt;-  (deps (universe))
&lt;/span&gt;   (action (run echo "Hello World!")))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And try running &lt;code&gt;dune build @helloworld&lt;/code&gt; twice. You'll notice it works as you might expect once, then appears to stop working:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;dune build @helloworld
Hello World!
&lt;span class="nv"&gt;$ &lt;/span&gt;dune build @helloworld
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Huh? No echo?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's because, without defining the &lt;code&gt;deps&lt;/code&gt; as &lt;code&gt;universe&lt;/code&gt;, &lt;code&gt;dune&lt;/code&gt; knows that since the last time we ran the &lt;code&gt;@helloworld&lt;/code&gt; build command... nothing changed! And so &lt;code&gt;dune&lt;/code&gt; does not do what it believes to be unnecessary work, and does not run the command we have defined the second time.&lt;/p&gt;

&lt;p&gt;This is particularly powerful for something like code generation, where if none of the input files have changed we can avoid wasting time to create build artifacts.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://dune.readthedocs.io/en/stable/concepts.html#dependency-specification"&gt;You can check out the full dependency definition specification&lt;/a&gt; to experiment, but for now know that &lt;code&gt;(deps (universe))&lt;/code&gt; will act similarly to a &lt;code&gt;npm&lt;/code&gt; script or &lt;code&gt;.PHONY&lt;/code&gt; target and execute every single time it is invoked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Elephant In The Room: Targets
&lt;/h2&gt;

&lt;p&gt;There's still once major concept we haven't covered: the &lt;code&gt;(target ...)&lt;/code&gt; settings for a rule. Targets are any file(s) you're creating with a rule, and they let do you more advanced things with &lt;code&gt;dune&lt;/code&gt;. The good news is that if you don't want or need more advanced dune features, you're fine ignoring this piece of configuration.&lt;/p&gt;

&lt;p&gt;For example, the command above is just an ephemeral side effect, so there's no point. Note, however, that &lt;code&gt;dune&lt;/code&gt; will actually &lt;em&gt;infer&lt;/em&gt; your targets for certain actions, and so the implications of configuring a target might pop up even if you neglect to explicitly set one. Most of the time, things will still "just work". But as you go deeper creating your own rules and you see strange behavior or errors mentioning targets, I would &lt;a href="https://dune.readthedocs.io/en/stable/dune-files.html?highlight=rule#inferred-rules"&gt;recommend reading up on them&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Running arbitrary tasks in your projects ("scripts"), is called a &lt;code&gt;dune&lt;/code&gt; "rule".&lt;/li&gt;
&lt;li&gt;Rules are written in a &lt;code&gt;dune&lt;/code&gt; file as S-Expressions.&lt;/li&gt;
&lt;li&gt;Rules have names called "aliases".&lt;/li&gt;
&lt;li&gt;Rules have dependencies (and will not run if dependencies have not changed since the last time the rule was invoked).&lt;/li&gt;
&lt;li&gt;Rules have actions, which define the command that is run to satisfy the rule&lt;/li&gt;
&lt;li&gt;Rules can be invoked by running &lt;code&gt;dune build @&lt;/code&gt; with the alias following, like &lt;code&gt;dune build @tailwind&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ocaml</category>
      <category>dune</category>
      <category>tutorial</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Remix: Sharing Your Index Layout with Sub-Routes</title>
      <dc:creator>Patrick Kilgore</dc:creator>
      <pubDate>Sun, 16 Jan 2022 20:00:34 +0000</pubDate>
      <link>https://forem.com/pckilgore/remix-sharing-your-index-layout-with-sub-routes-2856</link>
      <guid>https://forem.com/pckilgore/remix-sharing-your-index-layout-with-sub-routes-2856</guid>
      <description>&lt;p&gt;I've been poking at &lt;a href="https://remix.run/" rel="noopener noreferrer"&gt;Remix&lt;/a&gt; as a SSR framework. It appeals because I agree with the philosophy: react focused, leaning into web standards, and with good developer UX.&lt;/p&gt;

&lt;p&gt;But, similar to other convention-based frameworks, I quickly ran into a situation where I knew how to write the code but not how to implement it via convention.&lt;/p&gt;

&lt;p&gt;The site I'm building with Remix shares a layout between the index and its sub-pages. Essentially the index &lt;code&gt;/&lt;/code&gt; route is the home, and shares its layout with any &lt;code&gt;/subpage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Basically:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz07xl1cbspq347jix5io.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz07xl1cbspq347jix5io.png" alt="wireframe demonstrating desired mapping of route to layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Doesn't Work
&lt;/h2&gt;

&lt;p&gt;Naively, I started building out a layout with this file structure:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

routes/
└── index.tsx
└── subpage.tsx


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But remix considers &lt;code&gt;/subpage&lt;/code&gt; a peer, of &lt;code&gt;/&lt;/code&gt;, even if the url reads like &lt;code&gt;subpage&lt;/code&gt; is a child of &lt;code&gt;/&lt;/code&gt;.  And so the subpage route contains none of the shared layout defined in the index file.&lt;/p&gt;

&lt;p&gt;So clearly the &lt;code&gt;index.tsx&lt;/code&gt; file is not the right place to put shared layout code.  But where? &lt;/p&gt;

&lt;h2&gt;
  
  
  What Does Work
&lt;/h2&gt;

&lt;p&gt;The remix documentation has two other concepts that compose to solve this problem, &lt;em&gt;layout routes&lt;/em&gt; and &lt;em&gt;pathless routes&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layout Routes
&lt;/h3&gt;

&lt;p&gt;A layout route is a file with the same name as a directory:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

routes/
├── app
│   ├── index.tsx   # &amp;lt;-- page rendered inside layout
│   └── subpage.tsx # &amp;lt;-- page rendered inside layout
├── app.tsx         # &amp;lt;--- the layout file
└── index.tsx


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But that alone doesn't solve my problem unless I want the entire app to exist at a nested route &lt;code&gt;/app&lt;/code&gt; (or whatever). I don't.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pathless Routes
&lt;/h3&gt;

&lt;p&gt;The second concept is the pathless route, which is any folder that starts with &lt;code&gt;__&lt;/code&gt;.  This allows you to create nesting in the filesystem that isn't reflected in the url, for example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

routes/
├── app
│   ├── __admin
│   │   ├── admin-login.tsx # &amp;lt;-- renders at /app/admin-login
│   │   └── moderation.tsx  # &amp;lt;-- renders at /app/moderation
│   ├── page1.tsx           # &amp;lt;-- renders at /app/page1
│   └── page2.tsx           # &amp;lt;-- renders at /app/page2
├── app.tsx
└── index.tsx               # &amp;lt;-- renders at /


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Combining the Two with Index Pages
&lt;/h3&gt;

&lt;p&gt;Frankly, I didn't expect combining pathless and layout routes to work to work with &lt;code&gt;index&lt;/code&gt; pages, as index pages are usually a bit special in that they're usually expect to exist as &lt;em&gt;files&lt;/em&gt; not &lt;em&gt;directories&lt;/em&gt;. And especially not as directories starting with &lt;code&gt;__&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;But--credit to remix--the rules here compose well with indexes just as well as they do with other pages and routes.  Applying the rules above, I ended up with:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

routes/
├── __index
│   ├── index.tsx
│   └── subpage.tsx
└── __index.tsx


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Which renders exactly like you think it might:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejxztq7cjk5lx491l3hp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejxztq7cjk5lx491l3hp.png" alt="Screenshot of index route rendering correctly with shared layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdias73pid3udlzp0spm8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdias73pid3udlzp0spm8.png" alt="Screenshot of subpage route rendering correctly with shared layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;

&lt;p&gt;You can checkout code for the example above &lt;a href="https://github.com/pckilgore/remixlayoutex" rel="noopener noreferrer"&gt;on Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>remix</category>
      <category>react</category>
      <category>javascript</category>
      <category>layout</category>
    </item>
  </channel>
</rss>
