gatsby-plugin-modal-routing
Adds support for viewing gatsby pages within modals at their gatsby defined routes.
Examples
- https://gatsby-starter-with-gatsby-plugin-modal-routing.netlify.com/
 - https://gatsbygram-with-gatsby-plugin-modal-routing.netlify.com/
 
Install
npm install --save gatsby-plugin-modal-routingMotivation
The problem: how to handle modals (stateful routes) with gatsby’s page based routing?
We want a modal to open within the context of whatever page it was linked to, change the browser’s URL, and render server-side allowing permalink navigation.
Current Gatsby V2 examples which use PageRenderer flicker when re-rendering content
underneath the modal. This plugin aims to handle modal routing edge cases and provide
a consistent rendering experience with a flexible API.
How to use
Note that this plugin is currently in alpha, and this API is subject to change
Add the plugin to your gatsby-config.js:
// gatsby-config.js
module.exports = {
  plugins: [
    `gatsby-plugin-modal-routing`
  ]
];Plugin Options
module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-modal-routing`,
      options: {
        // A selector to set react-modal's app root to, default is `#___gatsby`
        // See http://reactcommunity.org/react-modal/accessibility/#app-element
        appElement: '#___gatsby',
        // Object of props that will be passed to the react-modal container
        // See http://reactcommunity.org/react-modal/#usage
        modalProps: { },
      }
    }
  ]
];Rendering page content in modals
Any gatsby page may be rendered in a modal if it is routed to appropriately (see next section below for creating a modal link).
The ModalRoutingContext React.Context component can be used to conditionally render
content if the page is rendered in a modal.
The Context consumer is passes an object with modal and closeTo properties to it’s
child render function
modal(boolean) - indicates if the page content will be rendered in a modal. Use
this to conditionally render modal content like a close button.
closeTo(string) - if the page content is rendering in a modal, denotes the
pathname of the page where the modal was opened, otherwise null.
Example:
// pages/modal-example.js
import React from 'react'
import { Link } from 'gatsby'
import { ModalRoutingContext } from 'gatsby-plugin-modal-routing'
const ModalExamplePage = () => (
  <ModalRoutingContext>
    {({ modal, closeTo }) => (
      <div>
        {modal ? (
          <Link to={modalCloseTo}>
            Close
          </Link>
        ) : (
          <header>
            <h1>
              Website Title
            </h1>
          </header>
        )}
        <h2>Modal Page</h2>
        <Link to="/">Go back to the homepage</Link>
      </div>
    )}
  </ModalRoutingContext>
)
export default ModalExamplePageOpening a page in a modal
Pages can be opened in a modal context by passing the { modal: true } flag to Link state.
Example:
// src/components/some-component.js
import { Link } from 'gatsby'
...
<Link
  to="/login/"
  state={{
    modal: true
  }}
>
  Login
</Link>gatsby-plugin-modal-routing also provides a Link component as a convenience to encapsulate
this flag for you.
This is equivalent to the example above:
// src/components/some-component.js
import { Link } from 'gatsby-plugin-modal-routing'
...
<Link
  to="/login/"
  asModal
>
  Login
</Link>Scroll State
When the site opens a modal, gatsby’s default scroll update is prevented, so that the underlying page remains scrolled at the same position.
When routing to a non-modal page from a modal, gatsby’s default scroll update is allowed, causing the page to scroll to the top. This is the case even if the non-modal page is the same as the underlying page.
To prevent this, pass the { noScroll: true } flag to Link state.
// src/components/modal-content.js
import { Link } from 'gatsby'
...
<Link
  to="/"
  state={{
    noScroll: true
  }}
>
  Close Modal
</Link>As a convenience, this plugin’s Link component will detect if the to pathname matches the
content rendered under the modal and set the noScroll flag for you.
// src/components/modal-content.js
import { Link } from 'gatsby-plugin-modal-routing'
...
<Link
  to="/"
>
  Close Modal
</Link>