├── plugins └── gatsby-plugin-top-layout │ ├── package.json │ ├── gatsby-ssr.js │ └── gatsby-browser.js ├── .prettierrc ├── .prettierignore ├── src ├── config.js ├── components │ ├── Link │ │ └── Link.jsx │ └── Hero │ │ ├── Hero.jsx │ │ └── Hero.builder.js ├── builder-settings.js ├── theme.js ├── layouts │ ├── RootLayout.jsx │ └── PageLayout.jsx └── templates │ └── LandingPage.jsx ├── .gitignore ├── LICENSE ├── package.json ├── gatsby-config.js └── README.md /plugins/gatsby-plugin-top-layout/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-plugin-top-layout" 3 | } 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "tabWidth": 2, 4 | "printWidth": 80, 5 | "singleQuote": true, 6 | "trailingComma": "none" 7 | } 8 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Project dependencies 2 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 3 | node_modules 4 | .cache/ 5 | # Build directory 6 | public/ 7 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | // using module.exports here so gatsby-config can read it 2 | module.exports = { 3 | // TODO: Replace next line with your own public API key 4 | builderAPIKey: '59bb518773c14842921abe05d5e2bee3' 5 | }; 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project dependencies 2 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 3 | node_modules 4 | .cache/ 5 | # Build directory 6 | public/ 7 | .DS_Store 8 | yarn-error.log 9 | -------------------------------------------------------------------------------- /src/components/Link/Link.jsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Link } from 'gatsby'; 3 | 4 | export default props => { 5 | const internal = props.target !== '_blank' && /^\/(?!\/)/.test(props.href); 6 | if (internal) { 7 | return ; 8 | } 9 | return ; 10 | }; 11 | -------------------------------------------------------------------------------- /src/builder-settings.js: -------------------------------------------------------------------------------- 1 | import { builder } from '@builder.io/react'; 2 | // a set of widgets you can use in the editor, optional. 3 | import '@builder.io/widgets'; 4 | /** 5 | * Import all custom components so you can use in the builder.io editor 6 | * https://www.builder.io/c/docs/custom-react-components 7 | */ 8 | import './components/Hero/Hero.builder'; 9 | import config from './config'; 10 | builder.init(config.builderAPIKey); 11 | -------------------------------------------------------------------------------- /plugins/gatsby-plugin-top-layout/gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/prefer-default-export, react/prop-types */ 2 | import React from 'react'; 3 | import RootLayout from '../../src/layouts/RootLayout'; 4 | import PageLayout from '../../src/layouts/PageLayout'; 5 | 6 | export const wrapRootElement = ({ element, props }) => { 7 | return {element}; 8 | }; 9 | 10 | export const wrapPageElement = ({ element, props }) => { 11 | return {element}; 12 | }; 13 | -------------------------------------------------------------------------------- /plugins/gatsby-plugin-top-layout/gatsby-browser.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/prefer-default-export, react/prop-types */ 2 | import React from 'react'; 3 | import RootLayout from '../../src/layouts/RootLayout'; 4 | import PageLayout from '../../src/layouts/PageLayout'; 5 | 6 | export const wrapRootElement = ({ element, props }) => { 7 | return {element}; 8 | }; 9 | 10 | export const wrapPageElement = ({ element, props }) => { 11 | return {element}; 12 | }; 13 | -------------------------------------------------------------------------------- /src/theme.js: -------------------------------------------------------------------------------- 1 | import { createMuiTheme } from '@material-ui/core'; 2 | import green from '@material-ui/core/colors/green'; 3 | 4 | export default createMuiTheme({ 5 | overrides: { 6 | MuiBackdrop: { 7 | invisible: { 8 | backgroundColor: 'transparent', 9 | backdropFilter: 'none' 10 | }, 11 | root: { 12 | backdropFilter: 'blur(2px)' 13 | } 14 | } 15 | }, 16 | typography: { 17 | fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif' 18 | }, 19 | palette: { 20 | primary: { main: 'rgba(28, 151, 204, 1)' }, 21 | secondary: green 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /src/layouts/RootLayout.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Helmet } from 'react-helmet'; 3 | import CssBaseline from '@material-ui/core/CssBaseline'; 4 | import { ThemeProvider } from '@material-ui/core/styles'; 5 | import theme from '../theme'; 6 | 7 | export default function RootLayout(props) { 8 | return ( 9 | 10 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */} 23 | 24 | {props.children} 25 | 26 | 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Builder.io 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 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-starter-builder", 3 | "description": "Example Gatsby, and Builder.io project", 4 | "dependencies": { 5 | "@builder.io/gatsby": "^1.0.11", 6 | "@builder.io/react": "^1.1.52", 7 | "@builder.io/widgets": "^1.2.0", 8 | "@material-ui/core": "^4.9.7", 9 | "gatsby": "^2.13.31", 10 | "gatsby-plugin-material-ui": "^3.0.0", 11 | "gatsby-plugin-react-helmet": "^3.0.4", 12 | "react": "^16.8.4", 13 | "react-dom": "^16.8.4", 14 | "react-helmet": "^5.2.0", 15 | "react-parallax": "^3.0.3" 16 | }, 17 | "keywords": [ 18 | "gatsby", 19 | "Builder.io", 20 | "Gatsby starter template" 21 | ], 22 | "license": "MIT", 23 | "main": "n/a", 24 | "scripts": { 25 | "clean": "gatsby clean", 26 | "start": "npm run develop", 27 | "build": "npm run clean && gatsby build", 28 | "develop": "npm run clean && gatsby develop", 29 | "deploy": "npm run clean && gatsby build --prefix-paths && gh-pages -d public", 30 | "format": "prettier --write \"./**/*.js{x,}\"" 31 | }, 32 | "devDependencies": { 33 | "gh-pages": "^2.2.0", 34 | "prettier": "^1.15.3" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const config = require('./src/config'); 3 | module.exports = { 4 | pathPrefix: '/gatsby-starter-builder', 5 | siteMetadata: { 6 | title: 'Gatsby + Builder.io Starter', 7 | description: 8 | 'This repo contains an example website that is built with Builder.io, and generate with Gatsby' 9 | }, 10 | plugins: [ 11 | 'gatsby-plugin-top-layout', 12 | { 13 | resolve: 'gatsby-plugin-material-ui', 14 | // If you want to use styled components you should change the injection order. 15 | options: { 16 | // stylesProvider: { 17 | // injectFirst: true, 18 | // }, 19 | } 20 | }, 21 | // If you want to use styled components you should add the plugin here. 22 | // 'gatsby-plugin-styled-components', 23 | 'gatsby-plugin-react-helmet', 24 | { 25 | resolve: '@builder.io/gatsby', 26 | options: { 27 | publicAPIKey: config.builderAPIKey, 28 | templates: { 29 | // Render every `landingPage` model as a new page using the 30 | // src/templates/LandingPage.jsx template based on the URL provided in Builder.io 31 | landingPage: path.resolve('src/templates/LandingPage.jsx') 32 | } 33 | } 34 | } 35 | ] 36 | }; 37 | -------------------------------------------------------------------------------- /src/components/Hero/Hero.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Image } from '@builder.io/react'; 3 | import { Parallax, Background } from 'react-parallax'; 4 | import Button from '@material-ui/core/Button'; 5 | import Typography from '@material-ui/core/Typography'; 6 | import Box from '@material-ui/core/Box'; 7 | 8 | export const Hero = props => { 9 | const { 10 | image, 11 | title, 12 | parallaxStrength, 13 | buttonLink, 14 | buttonText, 15 | height, 16 | darkMode 17 | } = props; 18 | 19 | return ( 20 | 26 | 31 | {title} 32 | 39 | 40 | 41 | {/* Builder optimized image with srcset, lazy, etc */} 42 | 43 | 44 | 45 | ); 46 | }; 47 | -------------------------------------------------------------------------------- /src/components/Hero/Hero.builder.js: -------------------------------------------------------------------------------- 1 | import { Builder } from '@builder.io/react'; 2 | import { Hero } from './Hero'; 3 | 4 | Builder.registerComponent(Hero, { 5 | name: 'Hero', 6 | // Optionally give a custom icon (image url - ideally a black on transparent bg svg or png) 7 | image: 8 | 'https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fd6d3bc814ffd47b182ec8345cc5438c0', 9 | inputs: [ 10 | { 11 | name: 'title', 12 | type: 'string', 13 | defaultValue: 'Your Title Here' 14 | }, 15 | { 16 | name: 'image', 17 | type: 'file', 18 | allowedFileTypes: ['jpeg', 'jpg', 'png', 'svg'], 19 | required: true, 20 | defaultValue: 21 | 'https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F52dcecf48f9c48cc8ddd8f81fec63236' 22 | }, 23 | { 24 | name: 'buttonLink', 25 | type: 'string', 26 | defaultValue: 'https://example.com' 27 | }, 28 | { 29 | name: 'buttonText', 30 | type: 'string', 31 | defaultValue: 'Click' 32 | }, 33 | { 34 | name: 'height', 35 | type: 'number', 36 | defaultValue: 400 37 | }, 38 | { 39 | name: 'darkMode', 40 | type: 'boolean', 41 | defaultValue: false 42 | }, 43 | // `advanced: true` hides this option under the "show advanced" toggle 44 | { 45 | name: 'parallaxStrength', 46 | type: 'number', 47 | advanced: true, 48 | defaultValue: 400 49 | } 50 | ] 51 | }); 52 | -------------------------------------------------------------------------------- /src/templates/LandingPage.jsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { graphql } from 'gatsby'; 3 | import { BuilderComponent } from '@builder.io/react'; 4 | import { Helmet } from 'react-helmet'; 5 | import Link from '../components/Link/Link'; 6 | 7 | const defaultDescription = 'Edit this in your entry for a better SEO'; 8 | 9 | const defaultTitle = 'Builder: Drag and Drop Page Building for Any Site'; 10 | 11 | function LandingPageTemplate({ data }) { 12 | const models = data?.allBuilderModels; 13 | const landingPage = models.landingPage[0]?.content; 14 | 15 | return ( 16 | <> 17 | 18 | {(landingPage && landingPage.data.title) || defaultTitle} 19 | 25 | 26 | {/** name of the model is landing page, change it if you decided to build*/} 27 | 32 | 33 | ); 34 | } 35 | 36 | export default LandingPageTemplate; 37 | 38 | export const landingPageQuery = graphql` 39 | query($path: String!) { 40 | allBuilderModels { 41 | landingPage( 42 | target: { urlPath: $path } 43 | limit: 1 44 | options: { cachebust: true } 45 | ) { 46 | content 47 | } 48 | } 49 | } 50 | `; 51 | -------------------------------------------------------------------------------- /src/layouts/PageLayout.jsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { graphql, StaticQuery } from 'gatsby'; 3 | import { BuilderComponent } from '@builder.io/react'; 4 | import { makeStyles } from '@material-ui/core/styles'; 5 | import Link from '../components/Link/Link'; 6 | import '../builder-settings'; 7 | import theme from '../theme'; 8 | 9 | const useStyles = makeStyles(them => ({ 10 | root: { 11 | padding: theme.spacing(1) 12 | }, 13 | header: {}, 14 | footer: {}, 15 | content: {} 16 | })); 17 | 18 | const query = graphql` 19 | query { 20 | allBuilderModels { 21 | header(limit: 1, options: { cachebust: true }) { 22 | content 23 | } 24 | footer(limit: 1, options: { cachebust: true }) { 25 | content 26 | } 27 | } 28 | } 29 | `; 30 | 31 | function PageLayout({ children }) { 32 | const classes = useStyles(); 33 | return ( 34 | 35 | {data => { 36 | const models = data.allBuilderModels; 37 | const header = models.header[0].content; 38 | const footer = models.footer[0].content; 39 | return ( 40 |
41 |
42 | 47 |
48 |
{children}
49 |
50 | 55 |
56 |
57 | ); 58 | }} 59 |
60 | ); 61 | } 62 | 63 | export default PageLayout; 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Builder.io Gatsby Example 2 | 3 | Gatsby starter with drag + drop page building with your React components via Builder.io's visual headless CMS 4 |
5 |
6 | Editor example 7 | 8 | ## Quick Start 9 | 10 | 1. **Sign up at Builder.io and Create a Gatsby site.** 11 | 12 | - Clone this repository or use `gatsby new` 13 | 14 | ```shell 15 | # create a new Gatsby site using this starter 16 | gatsby new my-builder-site https://github.com/BuilderIO/gatsby-starter-builder 17 | ``` 18 | 19 | - Grab a free account at [builder.io](https://builder.io/signup) and create a new space. Then return to this page and follow this [link](https://builder.io/fork-sample-org) to get set up with all the models used in this starter and some sample content to get you started. 20 | 21 | - In Builder.io, click on the Account icon on the left sidenav. 22 | 23 |
24 | Account icon in left sidenav 25 |
26 | 27 | - Change the Site URL to `http://localhost:8000` and copy the [Public API Key](https://builder.io/account/space). 28 | 29 | - In your code editor, add the Public API Key you just copied to [src/config.js](src/config.js) 30 | 31 | ```shell 32 | builderAPIKey: '59bb518773c14842921abe05d5e2bee3' <-- replace this with your API Key 33 | ``` 34 | 35 | 2. **Start developing.** 36 | 37 | Navigate into your new site’s directory and start it up. 38 | 39 | ```shell 40 | cd my-default-starter/ 41 | gatsby develop 42 | ``` 43 | 44 | Then start building pages in Builder! Use the pre-built templates, and components to create exactly what you want. This starter uses [@builder.io/gatsby plugin](https://github.com/BuilderIO/builder/tree/master/packages/gatsby) to fetch all your published pages and add them to your Gatsby build. 45 | 46 | 3. **Deploy.** 47 | 48 | [![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/BuilderIO/gatsby-starter-builder) 49 | 50 | For continuous deployment from netlify <> Builder.io : 51 | 52 | - Create a [build hook](https://docs.netlify.com/configure-builds/build-hooks/) in netlify 53 | - Add the build hook from last step to Builder.io global webhooks in your new [space settings](https://builder.io/account/space). 54 | 55 | ## 🧐 What's inside? 56 | 57 | This starter demonstrates creating dynamic pages in Builder.io on new URLs and generating them with Gatsby, as well as rendering specific parts of your site with Builder.io content via GraphQL queries (e.g. for pages, header, footer, etc) 58 | 59 | See: 60 | 61 | - [src/templates/LandingPage.jsx](src/templates/LandingPage.jsx) for using GraphQL to query and render Builder.io components and pages manually in parts of your Gatsby site and content 62 | - [src/layouts/PageLayout.jsx](src/layouts/PageLayout.jsx) for an example on wrapping your pages with content from `header` and `footer` model entries. 63 | - [@builder.io/gatsby](https://github.com/builderio/builder/tree/master/packages/gatsby) the plugin used in this starter to generate pages dynamically. 64 | 65 | ### Using your custom components in the editor 66 | 67 | > 👉**Tip: want to limit page building to only your components? Try [components only mode](https://builder.io/c/docs/guides/components-only-mode)** 68 | 69 | Register a component 70 | 71 | ```tsx 72 | import { Builder } from '@builder.io/react'; 73 | 74 | class SimpleText extends React.Component { 75 | render() { 76 | return

{this.props.text}

; 77 | } 78 | } 79 | 80 | Builder.registerComponent(SimpleText, { 81 | name: 'Simple Text', 82 | inputs: [{ name: 'text', type: 'string' }] 83 | }); 84 | ``` 85 | 86 | Then import it in the template or in your [builder-settings.js](src/builder-settings.js) 87 | 88 | ```tsx 89 | import './components/simple-text'; 90 | // ... 91 | ``` 92 | 93 | See: 94 | 95 | - [src/components/Hero/hero.builder.js](src/components/Hero/hero.builder.js) for an example of using a custom react component in the Builder.io visiaul editor. 96 | 97 | - [design systems example](https://github.com/BuilderIO/builder/tree/master/examples/react-design-system) for lots of examples using your deisgn system + custom components 98 | 99 | ### Mixed Content errors when hosting on insecure http 100 | 101 | Our editor uses the preview URL you supply for live editing. Because the editor is on `https`, the preview might not work correctly if your development setup uses http. To fix this, change your development set up to serve using https. Or, as a workaround, on Chrome you can allow insecure content on localhost, by toggling the `insecure content` option here [chrome://settings/content/siteDetails?site=http%3A%2F%2Flocalhost%3A9009](chrome://settings/content/siteDetails?site=http%3A%2F%2Flocalhost%3A8000) 102 | 103 | ## Prerequisites 104 | 105 | - Node 106 | - [Gatsby CLI](https://www.gatsbyjs.org/docs/) 107 | 108 | ## Available scripts 109 | 110 | ### `build` 111 | 112 | Build the static files into the `public` folder 113 | 114 | #### Usage 115 | 116 | ```sh 117 | $ npm run build 118 | ``` 119 | 120 | ### `clean` 121 | 122 | Runs `gatsby clean` command. 123 | 124 | #### Usage 125 | 126 | ```sh 127 | npm run clean 128 | ``` 129 | 130 | ### `develop` or `start` 131 | 132 | Runs the `clean` script and starts the gatsby develop server using the command `gatsby develop`. 133 | 134 | #### Usage 135 | 136 | ```sh 137 | npm run develop 138 | ``` 139 | 140 | ### `format` 141 | 142 | Formats code and docs according to our style guidelines using `prettier` 143 | 144 | #### Usage 145 | 146 | ```sh 147 | npm run format 148 | ``` 149 | 150 | ## CONTRIBUTING 151 | 152 | Contributions are always welcome, no matter how large or small. 153 | 154 | ## Learn more 155 | 156 | - [Official docs](https://www.builder.io/c/docs/getting-started) 157 | 158 | ## Gatsby starters and resources: 159 | 160 | | Resource | description | 161 | | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | 162 | | [@Builder.io/gatsby plugin](https://github.com/BuilderIO/builder/tree/master/packages/gatsby) | Plugin for sourcing content from Builder.io to Gatsby | 163 | | [Minimal starter](https://github.com/BuilderIO/builder/tree/master/examples/gatsby-minimal-starter) | Example of using Builder.io to build landing pages in Gatsby | 164 | | [Headless Shopify Store](https://github.com/BuilderIO/gatsby-builder-shopify) | Starter kit for building headless shopify storefronts with GatsbyJS and Builder.io [Demo](https://builder-shopify-starter.firebaseapp.com/) | 165 | --------------------------------------------------------------------------------