How best to include HTML with Gatsy site behind PrivateRoute?

Viewed 125

I want to put HTML code that has been generated by Javadoc within a Gatsby site, such that the HTML is accessible only via an authenticated route.

Thus my site might look something like this, using reach/router for routing:

    <Layout>
        <Router>
            <PrivateRoute path={'/docs/api1'} component={MyApiDisplay}/>
            <PrivateRoute path={'/docs/api2'} component={MyApiDisplay}/>
            <NotFoundComponent default/>
        </Router>
    </Layout>

where MyApiDisplay is some component which would display the Javadoc, perhaps in an IFrame.

What is the best way of including the HTML into the Gatsby site? The docs suggest using the static folder to hold the HTML, but that is public, which I don't want.

1 Answers
  1. Place your HTML in a content folder:
root
 |--content
 |   `--javadoc
 |       `--generated.html
  1. Point gatsby-source-filesystem to your html folder:
// gatsby-config.js
{
  resolve: `gatsby-source-filesystem`,
  options: {
    path: `${__dirname}/content/javadoc`,
    name: `javadoc`,
  },
},
  1. In gatsby-node.js, you can use loadNodeContent to read the raw html. Follow the API about creating nodes.
exports.onCreateNode = async ({
  node, loadNodeContent, actions
}) => {

  // only care about html file
  if (node.internal.type !== 'File' || node.internal.mediaType !== 'text/html') return;

  const { createNode } = actions;

  // read the raw html content
  const nodeContent = await loadNodeContent(node);

  // set up the new node
  const htmlNodeContent = {
    content: nodeContent,
    name: node.name, // take the file's name as identifier
    internal: {
      type: 'HTMLContent',
    }
    ...otherNecessaryMetaDataProps
  }

  createNode(htmlNode);
}
  1. Create your template component that queries and contains your HTML:
src/templates/blog-post.js

import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"
export default ({ data }) => {
  const generated = allHtmlContent // Make sure to deconstruct your query result correctly
  return (
    <Layout>
      <div>

        {*/ #### Supply your HTML markup to this template here #### /*}

        <div dangerouslySetInnerHTML={{ __html: generated }} />
      </div>
    </Layout>
  )
}


/* #### Query your HTML here #### */

export const query = graphql`
{
  allHtmlContent {
    edges {
      node {
        name
        content
      }
    }
  }
}
`
  1. Place your template component in a private route like you showed in your question.

Credit goes to @ksav and the question he linked.


EDIT

The output from Javadoc is not just HTML, it includes css, js and images. How does your answer change if these other file types need to be supported?

css

Make sure you import your styles correctly import "styles.css"; and the class names are set to what you need both in html and css.

javascript

This blog gives several possibilities. The answer here depends on your implementation. I recommend a new question for that.

images

Depends on whether you have absolute or relative paths. Absolute paths require no change. Relative paths might be a problem since Gatsby moves your files around. For relative paths I recommend a new question.

Related