├── .prettierrc ├── .prettierignore ├── docs └── images │ └── releaseID.png ├── src ├── images │ └── gatsby-icon.png ├── prismic │ └── linkResolver.js ├── pages │ ├── 404.js │ └── index.js ├── templates │ ├── previews.js │ └── page.js ├── components │ ├── header.js │ ├── layout.js │ ├── seo.js │ └── layout.css └── schemas │ ├── page.json │ └── homepage.json ├── gatsby-browser.js ├── gatsby-ssr.js ├── LICENSE ├── gatsby-node.js ├── .gitignore ├── package.json ├── gatsby-config.js ├── README.md └── getting-started.md /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "semi": false 4 | } 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .cache 2 | package.json 3 | package-lock.json 4 | public 5 | -------------------------------------------------------------------------------- /docs/images/releaseID.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prismicio/gatsby-starter-default/master/docs/images/releaseID.png -------------------------------------------------------------------------------- /src/images/gatsby-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prismicio/gatsby-starter-default/master/src/images/gatsby-icon.png -------------------------------------------------------------------------------- /gatsby-browser.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { PreviewStoreProvider } from 'gatsby-source-prismic' 3 | 4 | export const wrapRootElement = ({ element }) => ( 5 | {element} 6 | ) 7 | -------------------------------------------------------------------------------- /src/prismic/linkResolver.js: -------------------------------------------------------------------------------- 1 | const linkResolver = ({ node, key, value } = {}) => doc => { 2 | switch(doc.type) { 3 | case "homepage": return '/'; 4 | case "page": return `/${doc.uid}`; 5 | default: return "/"; 6 | } 7 | } 8 | 9 | module.exports = linkResolver -------------------------------------------------------------------------------- /src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | import Layout from "../components/layout" 4 | import SEO from "../components/seo" 5 | 6 | const NotFoundPage = () => ( 7 | 8 | 9 |

NOT FOUND

10 |

You just hit a route that doesn't exist... the sadness.

11 |
12 | ) 13 | 14 | export default NotFoundPage 15 | -------------------------------------------------------------------------------- /gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/ssr-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | import React from 'react' 9 | import { PreviewStoreProvider } from 'gatsby-source-prismic' 10 | 11 | export const wrapRootElement = ({ element }) => ( 12 | {element} 13 | ) 14 | -------------------------------------------------------------------------------- /src/templates/previews.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { withPreviewResolver } from 'gatsby-source-prismic' 3 | 4 | import Layout from '../components/layout' 5 | import linkResolver from '../prismic/linkResolver'; 6 | 7 | const PreviewPage = ({ isPreview, isLoading }) => { 8 | 9 | if (isPreview === false) return 'Not a preview!' 10 | 11 | return(

Loading

); 12 | } 13 | 14 | export default (props) => { 15 | const { repositoryName } = props.pageContext; 16 | return withPreviewResolver(PreviewPage, { repositoryName, linkResolver })(props) 17 | } -------------------------------------------------------------------------------- /src/components/header.js: -------------------------------------------------------------------------------- 1 | import { Link } from "gatsby" 2 | import PropTypes from "prop-types" 3 | import React from "react" 4 | 5 | const Header = ({ siteTitle }) => ( 6 |
12 |
19 |

20 | 27 | {siteTitle} 28 | 29 |

30 |
31 |
32 | ) 33 | 34 | Header.propTypes = { 35 | siteTitle: PropTypes.string, 36 | } 37 | 38 | Header.defaultProps = { 39 | siteTitle: ``, 40 | } 41 | 42 | export default Header 43 | -------------------------------------------------------------------------------- /src/schemas/page.json: -------------------------------------------------------------------------------- 1 | { 2 | "Main" : { 3 | "uid" : { 4 | "type" : "UID", 5 | "config" : { 6 | "label" : "uid" 7 | } 8 | }, 9 | "richtext" : { 10 | "type" : "StructuredText", 11 | "config" : { 12 | "multi" : "paragraph, preformatted, heading1, heading2, heading3, heading4, heading5, heading6, strong, em, hyperlink, image, embed, list-item, o-list-item, o-list-item", 13 | "allowTargetBlank" : true, 14 | "label" : "richtext" 15 | } 16 | } 17 | }, 18 | "SEO" : { 19 | "meta_title" : { 20 | "type" : "Text", 21 | "config" : { 22 | "label" : "meta_title" 23 | } 24 | }, 25 | "meta_description" : { 26 | "type" : "Text", 27 | "config" : { 28 | "label" : "meta_description" 29 | } 30 | }, 31 | "meta_author" : { 32 | "type" : "Text", 33 | "config" : { 34 | "label" : "meta_author" 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 gatsbyjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /src/schemas/homepage.json: -------------------------------------------------------------------------------- 1 | { 2 | "Main" : { 3 | "uid" : { 4 | "type" : "UID", 5 | "config" : { 6 | "label" : "uid" 7 | } 8 | }, 9 | "richtext" : { 10 | "type" : "StructuredText", 11 | "config" : { 12 | "multi" : "paragraph, preformatted, heading1, heading2, heading3, heading4, heading5, heading6, strong, em, hyperlink, image, embed, list-item, o-list-item, o-list-item", 13 | "allowTargetBlank" : true, 14 | "label" : "richtext" 15 | } 16 | }, 17 | "image" : { 18 | "type" : "Image", 19 | "config" : { 20 | "constraint" : { }, 21 | "thumbnails" : [ ], 22 | "label" : "image" 23 | } 24 | } 25 | }, 26 | "SEO" : { 27 | "meta_title" : { 28 | "type" : "Text", 29 | "config" : { 30 | "label" : "meta_title" 31 | } 32 | }, 33 | "meta_description" : { 34 | "type" : "Text", 35 | "config" : { 36 | "label" : "meta_description" 37 | } 38 | }, 39 | "meta_author" : { 40 | "type" : "Text", 41 | "config" : { 42 | "label" : "meta_author" 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/templates/page.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { graphql, Link } from 'gatsby'; 3 | import { RichText } from "prismic-reactjs"; 4 | import { withPreview } from 'gatsby-source-prismic' 5 | 6 | import Layout from "../components/layout"; 7 | import SEO from "../components/seo"; 8 | 9 | import linkResolver from '../prismic/linkResolver'; 10 | 11 | export const query = graphql` 12 | query($id: String!) { 13 | prismicPage(id: { eq: $id }) { 14 | data { 15 | meta_title 16 | richtext { 17 | raw 18 | } 19 | } 20 | } 21 | } 22 | `; 23 | 24 | const Page = ({ data }) => ( 25 | 26 | 27 | ( 32 | 33 | {content} 34 | 35 | )} 36 | /> 37 | 38 | ); 39 | 40 | Page.query = query; 41 | 42 | export default withPreview(Page) -------------------------------------------------------------------------------- /gatsby-node.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's Node APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/node-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | const path = require('path'); 9 | 10 | exports.createPages = async ({ graphql, actions }) => { 11 | const { createPage } = actions 12 | 13 | const { 14 | PRISMIC_PREVIEW_PATH, 15 | PRISMIC_API_KEY, 16 | PRISMIC_REPO_NAME, 17 | } = process.env; 18 | 19 | 20 | // this could be done conditionally 21 | createPage({ 22 | path: PRISMIC_PREVIEW_PATH, 23 | component: path.resolve(__dirname, 'src/templates/previews.js'), 24 | context: { 25 | repositoryName: PRISMIC_REPO_NAME, 26 | accessToken: PRISMIC_API_KEY, 27 | }, 28 | }); 29 | 30 | 31 | const pages = await graphql(`{ 32 | allPrismicPage { 33 | nodes { 34 | id 35 | uid 36 | lang 37 | } 38 | } 39 | }`); 40 | 41 | pages.data.allPrismicPage.nodes.forEach((page) => createPage({ 42 | path: "/" + page.uid, 43 | component: path.resolve(__dirname, 'src/templates/page.js'), 44 | context: { id: page.id }, 45 | })); 46 | } -------------------------------------------------------------------------------- /src/components/layout.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Layout component that queries for data 3 | * with Gatsby's useStaticQuery component 4 | * 5 | * See: https://www.gatsbyjs.org/docs/use-static-query/ 6 | */ 7 | 8 | import React from "react" 9 | import PropTypes from "prop-types" 10 | import { useStaticQuery, graphql } from "gatsby" 11 | 12 | import Header from "./header" 13 | import "./layout.css" 14 | 15 | const Layout = ({ children }) => { 16 | const data = useStaticQuery(graphql` 17 | query SiteTitleQuery { 18 | site { 19 | siteMetadata { 20 | title 21 | } 22 | } 23 | } 24 | `) 25 | 26 | return ( 27 | <> 28 |
29 |
36 |
{children}
37 |
38 | © {new Date().getFullYear()}, Built with 39 | {` `} 40 | Gatsby 41 |
42 |
43 | 44 | ) 45 | } 46 | 47 | Layout.propTypes = { 48 | children: PropTypes.node.isRequired, 49 | } 50 | 51 | export default Layout 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # dotenv environment variable files 55 | .env* 56 | 57 | # gatsby files 58 | .cache/ 59 | public 60 | 61 | # Mac files 62 | .DS_Store 63 | 64 | # Yarn 65 | yarn-error.log 66 | .pnp/ 67 | .pnp.js 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-starter-default", 3 | "private": true, 4 | "description": "A simple starter to get up and developing quickly with Gatsby", 5 | "version": "0.1.0", 6 | "author": "Kyle Mathews ", 7 | "dependencies": { 8 | "gatsby": "^2.22.15", 9 | "gatsby-image": "^2.4.5", 10 | "gatsby-plugin-manifest": "^2.4.9", 11 | "gatsby-plugin-offline": "^3.2.7", 12 | "gatsby-plugin-react-helmet": "^3.3.2", 13 | "gatsby-plugin-sharp": "^2.6.9", 14 | "gatsby-source-filesystem": "^2.3.8", 15 | "gatsby-source-prismic": "^3.1.1", 16 | "gatsby-transformer-sharp": "^2.5.3", 17 | "prismic-javascript": "^2.7.1", 18 | "prismic-reactjs": "^1.3.1", 19 | "prop-types": "^15.7.2", 20 | "react": "^16.12.0", 21 | "react-dom": "^16.12.0", 22 | "react-helmet": "^6.0.0" 23 | }, 24 | "devDependencies": { 25 | "prettier": "2.0.5" 26 | }, 27 | "keywords": [ 28 | "gatsby" 29 | ], 30 | "license": "MIT", 31 | "scripts": { 32 | "build": "gatsby build", 33 | "develop": "gatsby develop", 34 | "format": "prettier --write \"**/*.{js,jsx,json,md}\"", 35 | "start": "npm run develop", 36 | "serve": "gatsby serve", 37 | "clean": "gatsby clean", 38 | "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1" 39 | }, 40 | "repository": { 41 | "type": "git", 42 | "url": "https://github.com/gatsbyjs/gatsby-starter-default" 43 | }, 44 | "bugs": { 45 | "url": "https://github.com/gatsbyjs/gatsby/issues" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { Link, graphql } from "gatsby" 3 | import { RichText } from 'prismic-reactjs' 4 | import { withPreview } from 'gatsby-source-prismic' 5 | 6 | import Layout from "../components/layout" 7 | import SEO from "../components/seo" 8 | 9 | export const query = graphql`{ 10 | prismicHomepage { 11 | data { 12 | meta_title 13 | meta_description 14 | meta_author 15 | richtext { 16 | raw 17 | } 18 | image { 19 | url 20 | } 21 | } 22 | } 23 | allPrismicPage( sort: { 24 | fields: data___meta_title 25 | }) { 26 | edges { 27 | node { 28 | url 29 | id 30 | data { 31 | meta_title 32 | } 33 | } 34 | } 35 | } 36 | }` 37 | 38 | const IndexPage = ({ data }) => ( 39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 | 47 |
48 | 49 | {data.allPrismicPage.edges.map((edge, index, arr) => { 50 | 51 | const Elem = (props) => (Go to {edge.node.data.meta_title}); 52 | 53 | return (index < arr.length - 1) ? ( 54 | 55 |
56 |
) : ; 57 | })} 58 | 59 |
60 | ) 61 | 62 | IndexPage.query = query; 63 | 64 | export default withPreview(IndexPage) 65 | -------------------------------------------------------------------------------- /src/components/seo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SEO component that queries for data with 3 | * Gatsby's useStaticQuery React hook 4 | * 5 | * See: https://www.gatsbyjs.org/docs/use-static-query/ 6 | */ 7 | 8 | import React from "react" 9 | import PropTypes from "prop-types" 10 | import { Helmet } from "react-helmet" 11 | import { useStaticQuery, graphql } from "gatsby" 12 | 13 | function SEO({ description, lang, meta, title, author }) { 14 | const { site } = useStaticQuery( 15 | graphql` 16 | query { 17 | site { 18 | siteMetadata { 19 | title 20 | description 21 | author 22 | } 23 | } 24 | } 25 | ` 26 | ) 27 | 28 | const metaDescription = description || site.siteMetadata.description 29 | const metaAuthor = author || site.siteMetadata.author 30 | 31 | return ( 32 | 73 | ) 74 | } 75 | 76 | SEO.defaultProps = { 77 | lang: `en`, 78 | meta: [], 79 | description: ``, 80 | author: ``, 81 | } 82 | 83 | SEO.propTypes = { 84 | description: PropTypes.string, 85 | lang: PropTypes.string, 86 | meta: PropTypes.arrayOf(PropTypes.object), 87 | title: PropTypes.string.isRequired, 88 | author: PropTypes.string, 89 | } 90 | 91 | export default SEO 92 | -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | 2 | // Can be configured in gatsby-cloud 3 | process.env.PRISMIC_REPO_NAME = process.env.PRISMIC_REPO_NAME || "gatsby-starter-default"; 4 | 5 | 6 | // Release to preview 7 | process.env.PRISMIC_RELEASE_ID = process.env.PRISMIC_RELEASE_ID || "XtdZ4BIAACMANi0x"; 8 | 9 | // now to set up gatsby-cloud and then a preview 10 | // For redirecting from prismic to the page on gatsby-preview 11 | process.env.PRISMIC_PREVIEW_PATH = process.env.PRISMIC_PREVIEW_PATH || "/previews"; 12 | 13 | const accessToken = process.env.PRISMIC_API_KEY; 14 | 15 | const buildRelease = process.env.GATSBY_CLOUD && process.env.NODE_ENV === "development"; 16 | 17 | const linkResolver = require('./src/prismic/linkResolver'); 18 | 19 | const gastbySourcePrismicConfig = { 20 | resolve: 'gatsby-source-prismic', 21 | options: { 22 | repositoryName: process.env.PRISMIC_REPO_NAME, 23 | accessToken, 24 | linkResolver, 25 | 26 | schemas: { 27 | // Custom types mapped to schemas 28 | homepage: require("./src/schemas/homepage.json"), 29 | page: require('./src/schemas/page.json') 30 | }, 31 | 32 | releaseID: buildRelease ? process.env.PRISMIC_RELEASE_ID : "", 33 | 34 | // add prismic toolbar 35 | prismicToolbar: true 36 | } 37 | }; 38 | 39 | module.exports = { 40 | siteMetadata: { 41 | title: `Gatsby Default Starter`, 42 | description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`, 43 | author: `@gatsbyjs`, 44 | }, 45 | plugins: [ 46 | `gatsby-plugin-react-helmet`, 47 | { 48 | resolve: `gatsby-source-filesystem`, 49 | options: { 50 | name: `images`, 51 | path: `${__dirname}/src/images`, 52 | }, 53 | }, 54 | `gatsby-transformer-sharp`, 55 | `gatsby-plugin-sharp`, 56 | { 57 | resolve: `gatsby-plugin-manifest`, 58 | options: { 59 | name: `gatsby-starter-default`, 60 | short_name: `starter`, 61 | start_url: `/`, 62 | background_color: `#663399`, 63 | theme_color: `#663399`, 64 | display: `minimal-ui`, 65 | icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site. 66 | }, 67 | }, 68 | // this (optional) plugin enables Progressive Web App + Offline functionality 69 | // To learn more, visit: https://gatsby.dev/offline 70 | // `gatsby-plugin-offline`, 71 | gastbySourcePrismicConfig 72 | ], 73 | } 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gatsby default starter 2 | 3 | A starter for building websites with [Pismic](https://prismic.io) and [Gatsby](https:/gatsby.org) 4 | 5 | ## Getting started 6 | 7 | ### Requirements 8 | 9 | + [Node.js](https://nodejs.org/) 10 | 11 | ### Create codebase 12 | 13 | Click on "Use this repository" button to [create your own repository from this template](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-from-a-template). 14 | 15 | ### Create content in Prismic 16 | 17 | 1. Goto [Prismic](https://prismic.io) and create an account and repository if you do not already have one. 18 | 2. Copy the subdomain name of the repository to the `process.env.PRISMIC_REPO_NAME` environment variable. In this example the url. 19 | 2. Create a custom type, by copy the schemas from [src/schemas](https://github.com/prismicio/gatsby-starter-default/tree/master/src/schemas) in to the JSON editor and save. 20 | 3. Do this for each of the custom-types in the src/schemas directory then return to the repository dashboard and navigate to content and create some content for each of the custom-types. 21 | 4. Click __save -> publish -> publish now__. 22 | 23 | ### Preview a release 24 | 25 | 1. Select some content to edit and make a change and click __save -> publish -> publish it during a release__ 26 | 2. This will walk you though creating a new release. 27 | 3. Once the release is created go back to the repository dashboard and click on the name of the release name in the top bar navigation. 28 | 4. The release id can now be found in the url. in this example the release-id is `XtdZ4BIAACMANi0x`. 29 | ![](https://github.com/prismicio/gatsby-starter-default/tree/master/docs/images/releaseID.png) 30 | 5. Add this id to the environment variables in `gatsby-config.js` as `process.env.PRISMIC_RELEASE_ID`. 31 | 6. Create a preview in Prismic __settings -> previews -> create a preview__ set the name to `local-release` the domain to `http://localhost:8000` and set the preview path to `/previews`. 32 | 7. Add this preview path to `gatsby-config.js` as `process.env.PRISMIC_PREVIEW_PATH`. 33 | 8. To see the preview build run `GATSBY_CLOUD=true npm start` 34 | 35 | 36 | ## Gatsby cloud 37 | 38 | 1. Go to [gatsby.com](https://www.gatsbyjs.com/) and log-in with github and select __create a new site__. 39 | 2. Select __I have a gatsby site__. 40 | 3. Select the repository that this template has been used in. 41 | 4. For integrations choose __skip this step__. 42 | 5. Set the environment variables in gatsby cloud. 43 | 6. Click __save__ and __create site__ 44 | 45 | ### Webhooks 46 | 47 | Create two webhooks one for gatsby's production build and preview builds in prismic by following the [prismic user guide](https://user-guides.prismic.io/en/articles/790505-webhooks) and the urls that can be found for the project on gatsby.com underneath ___site settings -> webhooks__, 48 | -------------------------------------------------------------------------------- /getting-started.md: -------------------------------------------------------------------------------- 1 | # Getting started with Gatsby Cloud and Prismic 2 | ## Learn how to connect Gatsby Cloud with Prismic 3 | 4 | ## What is Gatsby Cloud and Prismic, and why use them together? 5 | [Prismic](https://prismic.io) is a headless CMS that content editors can use to edit and publish content. Gatsby Cloud allows you to integrate your site with Prismic in order to run efficient builds and preview content changes made in the CMS before publishing. 6 | 7 | ## Setting up a Prismic and Gatsby site 8 | First, you’ll need a Gatsby site with a [gatsby-source-prismic](https://www.gatsbyjs.org/packages/gatsby-source-prismic/) source plugin pulling data from Prismic. If you haven’t set that up yet, you can quickly create a new project by using the [prismic/gatsby-starter-default](https://github.com/prismicio/gatsby-starter-default) and signing up for an account at [prismic.io](https://prismic.io) 9 | 10 | ## Signing in to Gatsby Cloud 11 | Select Sign in with GitHub. You’ll be asked to authorize the Gatsby Cloud app with your GitHub account. If you need to request access to one or more repositories, you can click “request access” here or later, when creating an instance. 12 | 13 | Once signed in, configuring Gatsby Cloud with Prismic requires several steps that are walked through below. 14 | 15 | ## Creating an instance 16 | Once you’ve authenticated with Cloud and GitHub, you can create an instance from the [“Create a new Gatsby Cloud site”](https://gatsbyjs.com/dashboard/sites/create) page. 17 | 18 | Use the “I already have a Gatsby site” flow to manually integrate your site. 19 | 20 | ![](https://www.gatsbyjs.com/static/4b0022bee38a8bb336252ebcb49c3f1d/d0143/import-flow-start.png) 21 | 22 | Pick your Gatsby site from the list of GitHub repositories. You can use the search input to narrow down the list. 23 | 24 | ![](https://www.gatsbyjs.com/static/883c06163796af2e957a7d699cd04e9e/2bef9/select-repo.png) 25 | 26 | If you don’t see your site, it might be because it belongs to a GitHub organization, rather than your personal account. You can connect a new GitHub Organization. 27 | 28 | *Note: Repositories must contain one Gatsby project configured at their root to be enabled. Gatsby Cloud works best with Gatsby version 2.20.16 and higher.* 29 | 30 | ## Select branch and publish directory 31 | You’ll need to select a branch and then indicate the publish directory where the gatsby-config.js lives. If you leave the field blank, it defaults to the root of the site. 32 | 33 | ![](https://www.gatsbyjs.com/static/bab13665781f6f2f345f9a0ef84a1564/2bef9/select-branch.png) 34 | 35 | Once the branch and base directory are correct, select “Next.” 36 | 37 | ## Create the instance 38 | 39 | ![](https://www.gatsbyjs.com/static/edde9341fa9a163886607e753f4650a2/7ca1f/integration-step.png) 40 | 41 | ### Manual Integration 42 | First, click “Skip this step” to configure Prismic manually. 43 | 44 | 45 | Gatsby Cloud will automatically try and detect environment variables necessary in your gatsby-config.js. However — consider adding any additional variables that automatic detection may have missed. See [“Setting up Environment Variables”](#Setting up Environment Variables) for more info. 46 | 47 | Note that you will be able to add, delete, or update these later on in [“Site Settings”](#Setting up Environment Variables). 48 | 49 | Once you’ve added the necessary environment variables, you can press “Create site” which will create your instance in Gatsby Cloud! 50 | 51 | ### Site is Created 52 | 53 | After following the “Automatic Integration” or “Manual Integration” flow you now have an instance of Gatsby Cloud configured with environment variables and a provided Gatsby Preview instance you can share with your team. Woo-hoo! 54 | 55 | 56 | ### Setting up Environment Variables 57 | 58 | An environment variable references a value that can affect how running processes will behave on a computer, for example in staging and production environments. You must save environment variables in Gatsby Cloud to authorize your instance to pull source data from Prismic. 59 | 60 | 61 | __You will need to add into Gatsby Cloud any environment variable required for your app to run, such as deployment or test environment configuration settings.__ 62 | 63 | __You will also need to add in the following Gatsby Cloud-specific environment variables:__ 64 | 65 | | Variable | Description | 66 | | -------- | ----------- | 67 | | `PRISMIC_REPO_NAME` | prismic repository name | 68 | | `PRISMIC_API_KEY` | required if prismic api access is set to private | 69 | | `PRISMIC_PREVIEW_PATH` | a route to handle redirects from prismic to gatsby-preview | 70 | | `PRISMIC_RELEASE_ID` | A prismic release id to build in gatsby-previews | 71 | 72 | 73 | ### Environment variables in your `gatsby-config.js`: 74 | 75 | In your gatsby-config.js file, follow these steps: 76 | 77 | + In GitHub, navigate to the Gatsby site you selected for your instance 78 | 79 | + Navigate to the `gatsby-config.js` file at the root of the site - If you don’t have a `gatsby-config.js` file, [create one](https://www.gatsbyjs.org/docs/gatsby-config/?__hstc=247646936.26f7a3d4f1dbcdbe397a7c81785dbe96.1588758217561.1591118820931.1591176956114.23&__hssc=247646936.8.1591176956114&__hsfp=1004366510) 80 | 81 | + In the `gatsby-config.js` file, check that your `gatsby-source-prismic` config contains the `PRISMIC_REPO_NAME`, `PRISMIC_RELEASE_ID` and `PRISMIC_API_KEY` if using one. 82 | 83 | > Note: in this example `PRISMIC_PREVIEW_PATH` is used in `gatsby-node.js` to conditionally create a [preview route](#Adding a preview route). 84 | 85 | 86 | It should look something like this: 87 | 88 | 89 | ```js 90 | const buildRelease = process.env.GATSBY_CLOUD && process.env.NODE_ENV === "development"; 91 | 92 | module.exports = { 93 | plugins: [ 94 | resolve: 'gatsby-source-prismic', 95 | options: { 96 | repositoryName: process.env.PRISMIC_REPO_NAME, 97 | accessToken: process.env.PRISMIC_API_KEY || undefined, 98 | releaseID: buildRelease ? process.env.PRISMIC_RELEASE_ID : "", 99 | linkResolver: ({ node, key, value }) => doc => { 100 | // Your link resolver 101 | }, 102 | schemas: { 103 | // Custom types mapped to schemas 104 | }, 105 | } 106 | ] 107 | } 108 | ``` 109 | 110 | ## Setting up previews 111 | here we configure a preview in prismic that redirects to the gatbsy preview 112 | adding a release 113 | setting the release id in gatsby 114 | 115 | ### Adding a preview route 116 | 117 | When navigating from prismic to gatsby by using the preview button, the browser will be redirected to the path set when configuring the preview in prismic, (the default is `/previews`). An example of the page to redirect to the correct page from the preview rout can be found [here](https://github.com/prismicio/gatsby-starter-default/blob/master/src/templates/previews.js). 118 | 119 | A preview route will can conditionally be created by adding the follwing to the projects `gatsby-node.js` a when a preview build is run in gatsby. To build the preview route locally run `GATSBY_CLOUD=true npm start`. 120 | 121 | ```js 122 | // gatsby-node.js 123 | exports.createPages = async ({ graphql, actions }) => { 124 | const { createPage } = actions; 125 | const { GATSBY_CLOUD, NODE_ENV, PRISMIC_PREVIEW_PATH } = process.env 126 | 127 | if (GASTBY_CLOUD && NODE_ENV === 'development' && PRISMIC_PREVIEW_PATH) { 128 | 129 | createPage({ 130 | path: PRISMIC_PREVIEW_PATH, 131 | component: path.resolve(__dirname, 'src/templates/previews.js'), 132 | context: { 133 | repositoryName: PRISMIC_REPO_NAME, 134 | apiKey: PRISMIC_API_KEY, 135 | }, 136 | }); 137 | } 138 | } 139 | ``` 140 | 141 | 142 | ## Webhooks: Configuring your Gatsby site to work with Gatsby Cloud 143 | 144 | ### Setting up a webhook in Prismic 145 | To make a connection between prismic and Gatsby Cloud for your site, you’ll need to configure webhooks in prismic so that content changes can be pushed to Gatsby Cloud. 146 | 147 | You can add and edit necessary webhook information in two places in Gatsby Cloud: 148 | + During the “Create a new Site” process 149 | + After setting up an instance, on that instance’s Settings page 150 | 151 | 152 | [Prismic documentation on webhooks](https://user-guides.prismic.io/en/articles/790505-webhooks) 153 | 154 | ### Adding a Preview Webhook 155 | Navigate to your Gatsby Cloud instance and click __Site Settings__. Copy the Preview Webhook on this page. 156 | 157 | ![](https://www.gatsbyjs.com/static/c0c386bac17eb69ddcda78cd246ba1b5/fcbaf/webhook-preview.png) 158 | 159 | In your Prismic repository, go to __settings > webhooks__ and click __Create a webhook__. 160 | 161 | Name the webhook and paste the Preview webhook into the URL address field. 162 | ![](https://downloads.intercomcdn.com/i/o/178189637/bc4b8322fd6ddd2a75021158/configure.gif) 163 | 164 | And click __add this webhook__ 165 | 166 | Your new webhook will now trigger a Gatsby Cloud Preview update any time you trigger any of the events you selected! 167 | 168 | Then create another webhook for the using the build url from gatsby, and now the production build will automatically update when changes happen to the content in prismic. 169 | 170 | ## Wrapping Up 171 | At this point, you now have a prismic repository configured to best support Gatsby Cloud. Edit content and watch it appear live in Gatsby Cloud! 172 | -------------------------------------------------------------------------------- /src/components/layout.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-family: sans-serif; 3 | -ms-text-size-adjust: 100%; 4 | -webkit-text-size-adjust: 100%; 5 | } 6 | body { 7 | margin: 0; 8 | -webkit-font-smoothing: antialiased; 9 | -moz-osx-font-smoothing: grayscale; 10 | } 11 | article, 12 | aside, 13 | details, 14 | figcaption, 15 | figure, 16 | footer, 17 | header, 18 | main, 19 | menu, 20 | nav, 21 | section, 22 | summary { 23 | display: block; 24 | } 25 | audio, 26 | canvas, 27 | progress, 28 | video { 29 | display: inline-block; 30 | } 31 | audio:not([controls]) { 32 | display: none; 33 | height: 0; 34 | } 35 | progress { 36 | vertical-align: baseline; 37 | } 38 | [hidden], 39 | template { 40 | display: none; 41 | } 42 | a { 43 | background-color: transparent; 44 | -webkit-text-decoration-skip: objects; 45 | } 46 | a:active, 47 | a:hover { 48 | outline-width: 0; 49 | } 50 | abbr[title] { 51 | border-bottom: none; 52 | text-decoration: underline; 53 | text-decoration: underline dotted; 54 | } 55 | b, 56 | strong { 57 | font-weight: inherit; 58 | font-weight: bolder; 59 | } 60 | dfn { 61 | font-style: italic; 62 | } 63 | h1 { 64 | font-size: 2em; 65 | margin: 0.67em 0; 66 | } 67 | mark { 68 | background-color: #ff0; 69 | color: #000; 70 | } 71 | small { 72 | font-size: 80%; 73 | } 74 | sub, 75 | sup { 76 | font-size: 75%; 77 | line-height: 0; 78 | position: relative; 79 | vertical-align: baseline; 80 | } 81 | sub { 82 | bottom: -0.25em; 83 | } 84 | sup { 85 | top: -0.5em; 86 | } 87 | img { 88 | border-style: none; 89 | } 90 | svg:not(:root) { 91 | overflow: hidden; 92 | } 93 | code, 94 | kbd, 95 | pre, 96 | samp { 97 | font-family: monospace, monospace; 98 | font-size: 1em; 99 | } 100 | figure { 101 | margin: 1em 40px; 102 | } 103 | hr { 104 | box-sizing: content-box; 105 | height: 0; 106 | overflow: visible; 107 | } 108 | button, 109 | input, 110 | optgroup, 111 | select, 112 | textarea { 113 | font: inherit; 114 | margin: 0; 115 | } 116 | optgroup { 117 | font-weight: 700; 118 | } 119 | button, 120 | input { 121 | overflow: visible; 122 | } 123 | button, 124 | select { 125 | text-transform: none; 126 | } 127 | [type="reset"], 128 | [type="submit"], 129 | button, 130 | html [type="button"] { 131 | -webkit-appearance: button; 132 | } 133 | [type="button"]::-moz-focus-inner, 134 | [type="reset"]::-moz-focus-inner, 135 | [type="submit"]::-moz-focus-inner, 136 | button::-moz-focus-inner { 137 | border-style: none; 138 | padding: 0; 139 | } 140 | [type="button"]:-moz-focusring, 141 | [type="reset"]:-moz-focusring, 142 | [type="submit"]:-moz-focusring, 143 | button:-moz-focusring { 144 | outline: 1px dotted ButtonText; 145 | } 146 | fieldset { 147 | border: 1px solid silver; 148 | margin: 0 2px; 149 | padding: 0.35em 0.625em 0.75em; 150 | } 151 | legend { 152 | box-sizing: border-box; 153 | color: inherit; 154 | display: table; 155 | max-width: 100%; 156 | padding: 0; 157 | white-space: normal; 158 | } 159 | textarea { 160 | overflow: auto; 161 | } 162 | [type="checkbox"], 163 | [type="radio"] { 164 | box-sizing: border-box; 165 | padding: 0; 166 | } 167 | [type="number"]::-webkit-inner-spin-button, 168 | [type="number"]::-webkit-outer-spin-button { 169 | height: auto; 170 | } 171 | [type="search"] { 172 | -webkit-appearance: textfield; 173 | outline-offset: -2px; 174 | } 175 | [type="search"]::-webkit-search-cancel-button, 176 | [type="search"]::-webkit-search-decoration { 177 | -webkit-appearance: none; 178 | } 179 | ::-webkit-input-placeholder { 180 | color: inherit; 181 | opacity: 0.54; 182 | } 183 | ::-webkit-file-upload-button { 184 | -webkit-appearance: button; 185 | font: inherit; 186 | } 187 | html { 188 | font: 112.5%/1.45em georgia, serif; 189 | box-sizing: border-box; 190 | overflow-y: scroll; 191 | } 192 | * { 193 | box-sizing: inherit; 194 | } 195 | *:before { 196 | box-sizing: inherit; 197 | } 198 | *:after { 199 | box-sizing: inherit; 200 | } 201 | body { 202 | color: hsla(0, 0%, 0%, 0.8); 203 | font-family: georgia, serif; 204 | font-weight: normal; 205 | word-wrap: break-word; 206 | font-kerning: normal; 207 | -moz-font-feature-settings: "kern", "liga", "clig", "calt"; 208 | -ms-font-feature-settings: "kern", "liga", "clig", "calt"; 209 | -webkit-font-feature-settings: "kern", "liga", "clig", "calt"; 210 | font-feature-settings: "kern", "liga", "clig", "calt"; 211 | } 212 | img { 213 | max-width: 100%; 214 | margin-left: 0; 215 | margin-right: 0; 216 | margin-top: 0; 217 | padding-bottom: 0; 218 | padding-left: 0; 219 | padding-right: 0; 220 | padding-top: 0; 221 | margin-bottom: 1.45rem; 222 | } 223 | h1 { 224 | margin-left: 0; 225 | margin-right: 0; 226 | margin-top: 0; 227 | padding-bottom: 0; 228 | padding-left: 0; 229 | padding-right: 0; 230 | padding-top: 0; 231 | margin-bottom: 1.45rem; 232 | color: inherit; 233 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 234 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 235 | font-weight: bold; 236 | text-rendering: optimizeLegibility; 237 | font-size: 2.25rem; 238 | line-height: 1.1; 239 | } 240 | h2 { 241 | margin-left: 0; 242 | margin-right: 0; 243 | margin-top: 0; 244 | padding-bottom: 0; 245 | padding-left: 0; 246 | padding-right: 0; 247 | padding-top: 0; 248 | margin-bottom: 1.45rem; 249 | color: inherit; 250 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 251 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 252 | font-weight: bold; 253 | text-rendering: optimizeLegibility; 254 | font-size: 1.62671rem; 255 | line-height: 1.1; 256 | } 257 | h3 { 258 | margin-left: 0; 259 | margin-right: 0; 260 | margin-top: 0; 261 | padding-bottom: 0; 262 | padding-left: 0; 263 | padding-right: 0; 264 | padding-top: 0; 265 | margin-bottom: 1.45rem; 266 | color: inherit; 267 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 268 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 269 | font-weight: bold; 270 | text-rendering: optimizeLegibility; 271 | font-size: 1.38316rem; 272 | line-height: 1.1; 273 | } 274 | h4 { 275 | margin-left: 0; 276 | margin-right: 0; 277 | margin-top: 0; 278 | padding-bottom: 0; 279 | padding-left: 0; 280 | padding-right: 0; 281 | padding-top: 0; 282 | margin-bottom: 1.45rem; 283 | color: inherit; 284 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 285 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 286 | font-weight: bold; 287 | text-rendering: optimizeLegibility; 288 | font-size: 1rem; 289 | line-height: 1.1; 290 | } 291 | h5 { 292 | margin-left: 0; 293 | margin-right: 0; 294 | margin-top: 0; 295 | padding-bottom: 0; 296 | padding-left: 0; 297 | padding-right: 0; 298 | padding-top: 0; 299 | margin-bottom: 1.45rem; 300 | color: inherit; 301 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 302 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 303 | font-weight: bold; 304 | text-rendering: optimizeLegibility; 305 | font-size: 0.85028rem; 306 | line-height: 1.1; 307 | } 308 | h6 { 309 | margin-left: 0; 310 | margin-right: 0; 311 | margin-top: 0; 312 | padding-bottom: 0; 313 | padding-left: 0; 314 | padding-right: 0; 315 | padding-top: 0; 316 | margin-bottom: 1.45rem; 317 | color: inherit; 318 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 319 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 320 | font-weight: bold; 321 | text-rendering: optimizeLegibility; 322 | font-size: 0.78405rem; 323 | line-height: 1.1; 324 | } 325 | hgroup { 326 | margin-left: 0; 327 | margin-right: 0; 328 | margin-top: 0; 329 | padding-bottom: 0; 330 | padding-left: 0; 331 | padding-right: 0; 332 | padding-top: 0; 333 | margin-bottom: 1.45rem; 334 | } 335 | ul { 336 | margin-left: 1.45rem; 337 | margin-right: 0; 338 | margin-top: 0; 339 | padding-bottom: 0; 340 | padding-left: 0; 341 | padding-right: 0; 342 | padding-top: 0; 343 | margin-bottom: 1.45rem; 344 | list-style-position: outside; 345 | list-style-image: none; 346 | } 347 | ol { 348 | margin-left: 1.45rem; 349 | margin-right: 0; 350 | margin-top: 0; 351 | padding-bottom: 0; 352 | padding-left: 0; 353 | padding-right: 0; 354 | padding-top: 0; 355 | margin-bottom: 1.45rem; 356 | list-style-position: outside; 357 | list-style-image: none; 358 | } 359 | dl { 360 | margin-left: 0; 361 | margin-right: 0; 362 | margin-top: 0; 363 | padding-bottom: 0; 364 | padding-left: 0; 365 | padding-right: 0; 366 | padding-top: 0; 367 | margin-bottom: 1.45rem; 368 | } 369 | dd { 370 | margin-left: 0; 371 | margin-right: 0; 372 | margin-top: 0; 373 | padding-bottom: 0; 374 | padding-left: 0; 375 | padding-right: 0; 376 | padding-top: 0; 377 | margin-bottom: 1.45rem; 378 | } 379 | p { 380 | margin-left: 0; 381 | margin-right: 0; 382 | margin-top: 0; 383 | padding-bottom: 0; 384 | padding-left: 0; 385 | padding-right: 0; 386 | padding-top: 0; 387 | margin-bottom: 1.45rem; 388 | } 389 | figure { 390 | margin-left: 0; 391 | margin-right: 0; 392 | margin-top: 0; 393 | padding-bottom: 0; 394 | padding-left: 0; 395 | padding-right: 0; 396 | padding-top: 0; 397 | margin-bottom: 1.45rem; 398 | } 399 | pre { 400 | margin-left: 0; 401 | margin-right: 0; 402 | margin-top: 0; 403 | margin-bottom: 1.45rem; 404 | font-size: 0.85rem; 405 | line-height: 1.42; 406 | background: hsla(0, 0%, 0%, 0.04); 407 | border-radius: 3px; 408 | overflow: auto; 409 | word-wrap: normal; 410 | padding: 1.45rem; 411 | } 412 | table { 413 | margin-left: 0; 414 | margin-right: 0; 415 | margin-top: 0; 416 | padding-bottom: 0; 417 | padding-left: 0; 418 | padding-right: 0; 419 | padding-top: 0; 420 | margin-bottom: 1.45rem; 421 | font-size: 1rem; 422 | line-height: 1.45rem; 423 | border-collapse: collapse; 424 | width: 100%; 425 | } 426 | fieldset { 427 | margin-left: 0; 428 | margin-right: 0; 429 | margin-top: 0; 430 | padding-bottom: 0; 431 | padding-left: 0; 432 | padding-right: 0; 433 | padding-top: 0; 434 | margin-bottom: 1.45rem; 435 | } 436 | blockquote { 437 | margin-left: 1.45rem; 438 | margin-right: 1.45rem; 439 | margin-top: 0; 440 | padding-bottom: 0; 441 | padding-left: 0; 442 | padding-right: 0; 443 | padding-top: 0; 444 | margin-bottom: 1.45rem; 445 | } 446 | form { 447 | margin-left: 0; 448 | margin-right: 0; 449 | margin-top: 0; 450 | padding-bottom: 0; 451 | padding-left: 0; 452 | padding-right: 0; 453 | padding-top: 0; 454 | margin-bottom: 1.45rem; 455 | } 456 | noscript { 457 | margin-left: 0; 458 | margin-right: 0; 459 | margin-top: 0; 460 | padding-bottom: 0; 461 | padding-left: 0; 462 | padding-right: 0; 463 | padding-top: 0; 464 | margin-bottom: 1.45rem; 465 | } 466 | iframe { 467 | margin-left: 0; 468 | margin-right: 0; 469 | margin-top: 0; 470 | padding-bottom: 0; 471 | padding-left: 0; 472 | padding-right: 0; 473 | padding-top: 0; 474 | margin-bottom: 1.45rem; 475 | } 476 | hr { 477 | margin-left: 0; 478 | margin-right: 0; 479 | margin-top: 0; 480 | padding-bottom: 0; 481 | padding-left: 0; 482 | padding-right: 0; 483 | padding-top: 0; 484 | margin-bottom: calc(1.45rem - 1px); 485 | background: hsla(0, 0%, 0%, 0.2); 486 | border: none; 487 | height: 1px; 488 | } 489 | address { 490 | margin-left: 0; 491 | margin-right: 0; 492 | margin-top: 0; 493 | padding-bottom: 0; 494 | padding-left: 0; 495 | padding-right: 0; 496 | padding-top: 0; 497 | margin-bottom: 1.45rem; 498 | } 499 | b { 500 | font-weight: bold; 501 | } 502 | strong { 503 | font-weight: bold; 504 | } 505 | dt { 506 | font-weight: bold; 507 | } 508 | th { 509 | font-weight: bold; 510 | } 511 | li { 512 | margin-bottom: calc(1.45rem / 2); 513 | } 514 | ol li { 515 | padding-left: 0; 516 | } 517 | ul li { 518 | padding-left: 0; 519 | } 520 | li > ol { 521 | margin-left: 1.45rem; 522 | margin-bottom: calc(1.45rem / 2); 523 | margin-top: calc(1.45rem / 2); 524 | } 525 | li > ul { 526 | margin-left: 1.45rem; 527 | margin-bottom: calc(1.45rem / 2); 528 | margin-top: calc(1.45rem / 2); 529 | } 530 | blockquote *:last-child { 531 | margin-bottom: 0; 532 | } 533 | li *:last-child { 534 | margin-bottom: 0; 535 | } 536 | p *:last-child { 537 | margin-bottom: 0; 538 | } 539 | li > p { 540 | margin-bottom: calc(1.45rem / 2); 541 | } 542 | code { 543 | font-size: 0.85rem; 544 | line-height: 1.45rem; 545 | } 546 | kbd { 547 | font-size: 0.85rem; 548 | line-height: 1.45rem; 549 | } 550 | samp { 551 | font-size: 0.85rem; 552 | line-height: 1.45rem; 553 | } 554 | abbr { 555 | border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); 556 | cursor: help; 557 | } 558 | acronym { 559 | border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); 560 | cursor: help; 561 | } 562 | abbr[title] { 563 | border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); 564 | cursor: help; 565 | text-decoration: none; 566 | } 567 | thead { 568 | text-align: left; 569 | } 570 | td, 571 | th { 572 | text-align: left; 573 | border-bottom: 1px solid hsla(0, 0%, 0%, 0.12); 574 | font-feature-settings: "tnum"; 575 | -moz-font-feature-settings: "tnum"; 576 | -ms-font-feature-settings: "tnum"; 577 | -webkit-font-feature-settings: "tnum"; 578 | padding-left: 0.96667rem; 579 | padding-right: 0.96667rem; 580 | padding-top: 0.725rem; 581 | padding-bottom: calc(0.725rem - 1px); 582 | } 583 | th:first-child, 584 | td:first-child { 585 | padding-left: 0; 586 | } 587 | th:last-child, 588 | td:last-child { 589 | padding-right: 0; 590 | } 591 | tt, 592 | code { 593 | background-color: hsla(0, 0%, 0%, 0.04); 594 | border-radius: 3px; 595 | font-family: "SFMono-Regular", Consolas, "Roboto Mono", "Droid Sans Mono", 596 | "Liberation Mono", Menlo, Courier, monospace; 597 | padding: 0; 598 | padding-top: 0.2em; 599 | padding-bottom: 0.2em; 600 | } 601 | pre code { 602 | background: none; 603 | line-height: 1.42; 604 | } 605 | code:before, 606 | code:after, 607 | tt:before, 608 | tt:after { 609 | letter-spacing: -0.2em; 610 | content: " "; 611 | } 612 | pre code:before, 613 | pre code:after, 614 | pre tt:before, 615 | pre tt:after { 616 | content: ""; 617 | } 618 | @media only screen and (max-width: 480px) { 619 | html { 620 | font-size: 100%; 621 | } 622 | } 623 | --------------------------------------------------------------------------------