├── .editorconfig ├── .eslintrc ├── .gitignore ├── .npmrc ├── LICENSE ├── README.md ├── gatsby-config.js ├── package-lock.json ├── package.json ├── plugins └── svgo │ ├── gatsby-node.js │ └── package.json ├── postcss.config.js ├── sass ├── _bootstrap.scss ├── _global.scss ├── _settings.scss ├── _typography.scss ├── mixins │ └── _mixins.scss └── style.scss ├── server.js ├── server ├── config │ └── express.js └── index.js ├── src ├── components │ ├── button │ │ ├── _button.scss │ │ └── index.js │ ├── features │ │ ├── _features.scss │ │ └── index.js │ ├── footer │ │ ├── _footer.scss │ │ └── index.js │ ├── header │ │ ├── _header.scss │ │ └── index.js │ ├── how-to │ │ ├── _how-to.scss │ │ └── index.js │ ├── icon │ │ ├── github.icon │ │ └── index.js │ └── layout │ │ └── index.js ├── data │ └── data.json └── pages │ └── index.js └── static └── .gitkeep /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | charset = utf-8 8 | 9 | [{*.scss,*.css,*.js,*.json}] 10 | indent_style = space 11 | indent_size = 2 12 | 13 | [{package.json,*.yml,*.cjson}] 14 | indent_style = space 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": [ 4 | "@prototype-interactive/eslint-config/es9", 5 | "@prototype-interactive/eslint-config/addons/babel-parser", 6 | "@prototype-interactive/eslint-config/addons/browser", 7 | "@prototype-interactive/eslint-config/addons/node", 8 | "@prototype-interactive/eslint-config/addons/es-modules", 9 | "@prototype-interactive/eslint-config/addons/react", 10 | "@prototype-interactive/eslint-config/addons/jest" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # https://github.com/wearehive/project-guidelines/blob/master/.gitignore 2 | 3 | # Gatsby 4 | .cache/ 5 | public/ 6 | 7 | ### Node ### 8 | 9 | # Logs 10 | logs 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # Optional npm cache directory 16 | .npm 17 | 18 | # Dependency directories 19 | /node_modules 20 | /jspm_packages 21 | /bower_components 22 | 23 | # Yarn Integrity file 24 | .yarn-integrity 25 | 26 | # Optional eslint cache 27 | .eslintcache 28 | 29 | # dotenv environment variables file(s) 30 | .env 31 | .env.* 32 | 33 | #Build generated 34 | dist/ 35 | build/ 36 | 37 | 38 | ### SublimeText ### 39 | # cache files for sublime text 40 | *.tmlanguage.cache 41 | *.tmPreferences.cache 42 | *.stTheme.cache 43 | 44 | # workspace files are user-specific 45 | *.sublime-workspace 46 | 47 | # project files should be checked into the repository, unless a significant 48 | # proportion of contributors will probably not be using SublimeText 49 | # *.sublime-project 50 | 51 | 52 | ### VisualStudioCode ### 53 | .vscode/* 54 | !.vscode/settings.json 55 | !.vscode/tasks.json 56 | !.vscode/launch.json 57 | !.vscode/extensions.json 58 | 59 | ### WebStorm/IntelliJ ### 60 | /.idea 61 | modules.xml 62 | *.ipr 63 | 64 | 65 | ### System Files ### 66 | .DS_Store 67 | 68 | # Windows thumbnail cache files 69 | Thumbs.db 70 | ehthumbs.db 71 | ehthumbs_vista.db 72 | 73 | # Folder config file 74 | Desktop.ini 75 | 76 | # Recycle Bin used on file shares 77 | $RECYCLE.BIN/ 78 | 79 | # Thumbnails 80 | ._* 81 | 82 | # Files that might appear in the root of a volume 83 | .DocumentRevisions-V100 84 | .fseventsd 85 | .Spotlight-V100 86 | .TemporaryItems 87 | .Trashes 88 | .VolumeIcon.icns 89 | .com.apple.timemachine.donotpresent 90 | 91 | # Elastic Beanstalk Files 92 | 93 | .elasticbeanstalk/* 94 | !.elasticbeanstalk/*.cfg.yml 95 | !.elasticbeanstalk/*.global.yml -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Prototype Interactive 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gatsby React Boilerplate 2 | 3 | ### Requirements 4 | 5 | - [Node.js](http://nodejs.org): for all the magic 6 | - [Gatsby](https://www.gatsbyjs.org/docs/) 7 | 8 | ### Features 9 | 10 | - Basic configuration and folder structure 11 | - Uses postcss and sass (with autoprefixer and pixrem) 12 | - Uses [Bootstrap 4](http://getbootstrap.com/) grid 13 | - Leaves the styling to you 14 | - Uses data from local json files 15 | - Contains Node.js server code for easy, secure, and fast hosting 16 | - [SVG sprites](https://css-tricks.com/svg-sprites-use-better-icon-fonts/): Add your icons in `components/icon` as .icon files and use them. 17 | 18 | ### How to proceed 19 | 20 | 1. Prepare a coffee 21 | 1. Run: `npm i` to install the dependencies 22 | 1. Run: `npm run dev` to run Gatsby 23 | 1. You should see shortly some text that says `The development server is listening at: http://localhost:8000`. Open that address in your browser and… 24 | 1. Start coding! 25 | 26 | ### How to build 27 | 28 | 1. Run: `npm run build` to build website into `/public` folder 29 | 30 | ### Considerations 31 | 32 | - **RTL**: The usual method of generating different css file for RTL pages (as seen in static-html-boilerplate) will not work out of the box here since Gatsby pulls all the css together, this means the RTL css will override the LTR one. 33 | -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | siteMetadata: { 3 | title: `Gatsby Default Starter`, 4 | }, 5 | plugins: [ 6 | `gatsby-plugin-react-helmet`, 7 | `svgo`, 8 | `gatsby-plugin-sass`, 9 | `gatsby-plugin-postcss`, 10 | { 11 | resolve: `gatsby-source-filesystem`, 12 | options: { 13 | name: `data`, 14 | path: `${__dirname}/src/data/`, 15 | }, 16 | }, 17 | `gatsby-transformer-json` 18 | ], 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-react-boilerplate", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "develop": "gatsby develop", 8 | "build": "gatsby build", 9 | "serve": "gatsby serve", 10 | "start": "node server.js", 11 | "gh-pages": "gatsby build --prefix-paths && gh-pages -d public", 12 | "lint": "eslint src --fix", 13 | "dev": "(shx --silent rm -rf public || shx true) && gatsby develop", 14 | "server": "cross-env NODE_ENV=development DEBUG=api nodemon server.js" 15 | }, 16 | "author": "Prototype Interactive", 17 | "license": "MIT", 18 | "dependencies": { 19 | "basic-auth": "^2.0.1", 20 | "compression": "^1.7.3", 21 | "debug": "^4.1.1", 22 | "express": "^4.16.4", 23 | "helmet": "^3.15.0", 24 | "react-helmet": "^5.2.0", 25 | "serve-static": "^1.13.2" 26 | }, 27 | "devDependencies": { 28 | "@prototype-interactive/eslint-config": "^0.1.1", 29 | "autoprefixer": "^9.4.4", 30 | "bootstrap": "^4.2.1", 31 | "cross-env": "^5.2.0", 32 | "eslint": "^5.12.0", 33 | "gatsby": "^2.0.115", 34 | "gatsby-plugin-google-analytics": "^2.0.9", 35 | "gatsby-plugin-postcss": "^2.0.2", 36 | "gatsby-plugin-postcss-sass": "^1.0.22", 37 | "gatsby-plugin-react-helmet": "^3.0.5", 38 | "gatsby-plugin-sass": "^2.0.7", 39 | "gatsby-source-filesystem": "^2.0.13", 40 | "gatsby-transformer-json": "^2.1.7", 41 | "gh-pages": "^2.0.1", 42 | "husky": "^1.3.1", 43 | "prettier": "^1.15.3", 44 | "pretty-quick": "^1.8.0", 45 | "react": "^16.7.0", 46 | "react-dom": "^16.7.0", 47 | "shx": "^0.3.2", 48 | "svg-sprite-loader": "^4.1.3" 49 | }, 50 | "repository": { 51 | "type": "git", 52 | "url": "git+https://github.com/PrototypeInteractive/gatsby-react-boilerplate.git" 53 | }, 54 | "bugs": { 55 | "url": "https://github.com/PrototypeInteractive/gatsby-react-boilerplate/issues" 56 | }, 57 | "homepage": "https://github.com/PrototypeInteractive/gatsby-react-boilerplate#readme" 58 | } 59 | -------------------------------------------------------------------------------- /plugins/svgo/gatsby-node.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | exports.onCreateWebpackConfig = ({ stage, actions }) => { 4 | var svgFiles = /\.icon$/; 5 | var svgLoader = `svg-sprite-loader`; 6 | 7 | switch (stage) { 8 | case `develop`: 9 | case `develop-html`: 10 | case `build-html`: 11 | case `build-javascript`: { 12 | actions.setWebpackConfig({ 13 | module: { 14 | rules: [ 15 | { 16 | test: svgFiles, 17 | use: [`svg-sprite-loader`] 18 | } 19 | ] 20 | } 21 | }); 22 | } 23 | default: { 24 | return; 25 | } 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /plugins/svgo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svgo" 3 | } 4 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | const autoprefixer = require("autoprefixer"); 2 | 3 | module.exports = () => ({ 4 | plugins: [ 5 | autoprefixer({ 6 | browsers: ["last 2 versions"] 7 | }) 8 | ] 9 | }); 10 | -------------------------------------------------------------------------------- /sass/_bootstrap.scss: -------------------------------------------------------------------------------- 1 | @import "../node_modules/bootstrap/scss/functions"; 2 | @import "../node_modules/bootstrap/scss/variables"; 3 | @import "../node_modules/bootstrap/scss/mixins"; 4 | @import "../node_modules/bootstrap/scss/reboot"; 5 | @import "../node_modules/bootstrap/scss/type"; 6 | @import "../node_modules/bootstrap/scss/grid"; 7 | @import "../node_modules/bootstrap/scss/transitions"; 8 | @import "../node_modules/bootstrap/scss/media"; 9 | @import "../node_modules/bootstrap/scss/utilities"; 10 | 11 | -------------------------------------------------------------------------------- /sass/_global.scss: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | position: relative; 4 | width: 100%; 5 | height: 100%; 6 | } 7 | 8 | .visually-hidden { 9 | position: absolute; 10 | overflow: hidden; 11 | clip: rect(0 0 0 0); 12 | height: 1px; 13 | width: 1px; 14 | margin: -1px; 15 | padding: 0; 16 | border: 0; 17 | } 18 | -------------------------------------------------------------------------------- /sass/_settings.scss: -------------------------------------------------------------------------------- 1 | $color_main: #f04e30; 2 | $color_border: #e3e3e3; 3 | $color_text: #505457; 4 | $color_light_text: #7f8a8e; 5 | $color_dark_text: #494d51; 6 | -------------------------------------------------------------------------------- /sass/_typography.scss: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Helvetica", "Arial", sans-serif; 3 | font-size: 20px; 4 | color: $color_text; 5 | } 6 | -------------------------------------------------------------------------------- /sass/mixins/_mixins.scss: -------------------------------------------------------------------------------- 1 | $mq-extend-flag: true !global; 2 | //***************************************** 3 | // UTILITIES 4 | //***************************************** 5 | @mixin cf() { 6 | &:after { 7 | content: ""; 8 | display: table; 9 | clear: both; 10 | } 11 | } 12 | 13 | @mixin text-clamp($font-size, $line-height, $lines) { 14 | font-size: $font-size; 15 | line-height: $line-height; 16 | height: $lines * $font-size * $line-height; 17 | overflow: hidden; 18 | text-overflow: ellipsis; 19 | @supports (-webkit-line-clamp: 1) { 20 | display: -webkit-box; 21 | -webkit-line-clamp: $lines; 22 | -webkit-box-orient: vertical; 23 | } 24 | } 25 | 26 | @mixin unselectable() { 27 | user-select: none; 28 | } 29 | 30 | @mixin placeholder() { 31 | ::-webkit-input-placeholder { 32 | @content; 33 | } 34 | :-moz-placeholder { 35 | @content; 36 | } 37 | ::-moz-placeholder { 38 | @content; 39 | } 40 | :-ms-input-placeholder { 41 | @content; 42 | } 43 | } 44 | 45 | @mixin mobile-detect() { 46 | display: none; 47 | @media (max-width: 1024px) and (orientation: landscape), 48 | (max-width: 1024px) and (orientation: portrait) { 49 | display: block; 50 | } 51 | } 52 | 53 | @mixin retina() { 54 | $mq-extend-flag: false !global; 55 | @media only screen and (-webkit-min-device-pixel-ratio: 1.5), 56 | only screen and (min--moz-device-pixel-ratio: 1.5), 57 | only screen and (-o-min-device-pixel-ratio: 3/2), 58 | only screen and (min-device-pixel-ratio: 1.5), 59 | only screen and (min-resolution: 192dpi) { 60 | @content; 61 | } 62 | $mq-extend-flag: true !global; 63 | } 64 | -------------------------------------------------------------------------------- /sass/style.scss: -------------------------------------------------------------------------------- 1 | @import 'settings'; 2 | @import 'mixins/mixins'; 3 | @import 'bootstrap'; 4 | @import 'global'; 5 | @import 'typography'; 6 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | require('./server/index.js'); 2 | -------------------------------------------------------------------------------- /server/config/express.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var debug = require("debug")("api"); 3 | 4 | var express = require("express"); 5 | var serveStatic = require("serve-static"); 6 | var compression = require("compression"); 7 | var helmet = require("helmet"); 8 | 9 | module.exports = function(app) { 10 | app.use( 11 | helmet({ 12 | hsts: false, 13 | noSniff: false 14 | }) 15 | ); 16 | 17 | app.use(compression()); 18 | 19 | app.use(function(req, res, next) { 20 | res.setHeader("Access-Control-Allow-Origin", "*"); 21 | res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE"); 22 | res.setHeader( 23 | "Access-Control-Allow-Headers", 24 | "Origin, X-Requested-With, Content-Type, Accept" 25 | ); 26 | res.setHeader("Access-Control-Allow-Credentials", true); 27 | 28 | if (process.env.NODE_ENV !== "production") { 29 | res.setHeader("X-Robots-Tag", "noindex, nofollow"); 30 | } 31 | 32 | next(); 33 | }); 34 | 35 | app.get("/robots.txt", function(req, res, next) { 36 | if (process.env.NODE_ENV !== "production") { 37 | res.end(); 38 | } else { 39 | next(); 40 | } 41 | }); 42 | 43 | app.use( 44 | serveStatic("public", { 45 | index: ["index.html"], 46 | dotfiles: "ignore", 47 | maxAge: process.env.NODE_ENV !== "production" ? "0d" : "7d", 48 | setHeaders: setCustomCacheControl 49 | }) 50 | ); 51 | 52 | app.get("*", function(req, res) { 53 | res.status(404).end(); 54 | }); 55 | 56 | debug("--------------------------"); 57 | debug("☕️ "); 58 | debug("Starting Server"); 59 | debug("Environment: " + process.env.NODE_ENV); 60 | 61 | function setCustomCacheControl(res, path) { 62 | if (serveStatic.mime.lookup(path) === "text/html") { 63 | res.setHeader("Cache-Control", "public, max-age=0"); 64 | } 65 | } 66 | }; 67 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var express = require("express"); 4 | var debug = require("debug")("api"); 5 | var app = new express(); 6 | 7 | // express configs 8 | require("./config/express")(app); 9 | 10 | // start app 11 | app.listen(process.env.PORT || 8080, error => { 12 | if (!error) { 13 | debug(`📡 Running on port: ${process.env.PORT || 8080}`); 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /src/components/button/_button.scss: -------------------------------------------------------------------------------- 1 | .button { 2 | display: inline-block; 3 | appearance: none; 4 | border: solid 1px black; 5 | color: black; 6 | height: 50px; 7 | line-height: 50px; 8 | text-align: center; 9 | padding: 0 14px; 10 | text-transform: uppercase; 11 | font-size: 20px; 12 | font-weight: 500; 13 | position: relative; 14 | &:hover, 15 | &:focus, 16 | &:visited, 17 | &:active { 18 | color: black; 19 | text-decoration: none; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/components/button/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import './_button.scss'; 5 | 6 | const Button = (props) => ( 7 | 8 | {props.text} 9 | 10 | ); 11 | 12 | Button.propTypes = { 13 | link: PropTypes.string.isRequired, 14 | className: PropTypes.string, 15 | text: PropTypes.string.isRequired, 16 | }; 17 | 18 | Button.defaultProps = { 19 | className: '', 20 | }; 21 | 22 | export default Button; 23 | -------------------------------------------------------------------------------- /src/components/features/_features.scss: -------------------------------------------------------------------------------- 1 | .features { 2 | background-color: #f4f4f4; 3 | padding: 90px 0; 4 | &-title { 5 | font-weight: bold; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/components/features/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './_features.scss'; 3 | 4 | import { StaticQuery, graphql } from 'gatsby'; 5 | 6 | const Features = () => ( 7 | ( 22 |
23 |
24 |
25 |
26 |

Features

27 |
28 |
29 |
30 |
31 |
    32 | {data.allDataJson.edges[0].node.features.map((item, i) => ( 33 |
  • 34 | {item.title} 35 |
  • 36 | ))} 37 |
38 |
39 |
40 |
41 |
42 | ) } /> 43 | ); 44 | 45 | export default Features; 46 | -------------------------------------------------------------------------------- /src/components/footer/_footer.scss: -------------------------------------------------------------------------------- 1 | .footer { 2 | width: 100%; 3 | background-color: #333; 4 | &-content { 5 | height: 120px; 6 | display: flex; 7 | align-items: center; 8 | justify-content: space-between; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/components/footer/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Icon from '../icon'; 3 | import Github from '../icon/github.icon'; 4 | import './_footer.scss'; 5 | 6 | const Footer = () => ( 7 | 23 | ); 24 | 25 | export default Footer; 26 | -------------------------------------------------------------------------------- /src/components/header/_header.scss: -------------------------------------------------------------------------------- 1 | .header { 2 | width: 100%; 3 | &-content { 4 | height: 120px; 5 | display: flex; 6 | align-items: center; 7 | justify-content: space-between; 8 | } 9 | &-nav-list { 10 | margin: 0; 11 | padding: 0; 12 | list-style-type: none; 13 | display: flex; 14 | align-items: center; 15 | justify-content: space-between; 16 | &-item { 17 | margin-right: 10px; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/components/header/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import './_header.scss'; 4 | 5 | const Header = () => ( 6 |
7 |
8 |
9 |
10 |
11 | Gatsby React Boilerplate 12 | 22 |
23 |
24 |
25 |
26 |
27 | ); 28 | 29 | export default Header; 30 | -------------------------------------------------------------------------------- /src/components/how-to/_how-to.scss: -------------------------------------------------------------------------------- 1 | .howto { 2 | background-color: #fff; 3 | padding: 90px 0; 4 | &-title { 5 | font-weight: bold; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/components/how-to/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import './_how-to.scss'; 4 | 5 | import { StaticQuery, graphql } from 'gatsby'; 6 | 7 | const HowTos = () => ( 8 | ( 23 |
24 |
25 |
26 |
27 |

How to

28 |
29 |
30 |
31 |
32 |
    33 | {data.allDataJson.edges[0].node.howTo.map((item, i) => ( 34 |
  1. 35 | {item.title} 36 |
  2. 37 | ))} 38 |
39 |
40 |
41 |
42 |
43 | ) } /> 44 | ); 45 | 46 | export default HowTos; 47 | -------------------------------------------------------------------------------- /src/components/icon/github.icon: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/components/icon/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const Icon = (props) => ( 5 | 10 | 11 | 12 | ); 13 | 14 | Icon.propTypes = { 15 | viewBox: PropTypes.string, 16 | id: PropTypes.string, 17 | width: PropTypes.oneOf(['number', 'string']), 18 | height: PropTypes.oneOf(['number', 'string']), 19 | fill: PropTypes.string, 20 | }; 21 | 22 | export default Icon; 23 | -------------------------------------------------------------------------------- /src/components/layout/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Helmet from 'react-helmet'; 4 | import Header from '../header'; 5 | import Footer from '../footer'; 6 | 7 | import '../../../sass/style.scss'; 8 | 9 | const TemplateWrapper = ({ children }) => ( 10 |
11 | 12 |
13 | {children} 14 |
15 |
16 | ); 17 | 18 | TemplateWrapper.propTypes = { 19 | children: PropTypes.element.isRequired, 20 | }; 21 | 22 | export default TemplateWrapper; 23 | -------------------------------------------------------------------------------- /src/data/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "features": [ 3 | { 4 | "title": "Now runs gatsby 2!" 5 | }, 6 | { 7 | "title": "Basic configuration and folder structure" 8 | }, 9 | { 10 | "title": "Uses postcss and sass with autoprefixer" 11 | }, 12 | { 13 | "title": "Uses Bootstrap 4" 14 | }, 15 | { 16 | "title": "Leaves the styling to you" 17 | }, 18 | { 19 | "title": "Uses data from local json files" 20 | }, 21 | { 22 | "title": "Contains Node.js server code for easy, secure, and fast hosting" 23 | }, 24 | { 25 | "title": "SVG sprites: Add your icons in `components/icon` as .icon files and use them." 26 | } 27 | ], 28 | "howTo": [ 29 | { 30 | "title": "Prepare a coffee" 31 | }, 32 | { 33 | "title": "Run: `npm i` to install the dependencies" 34 | }, 35 | { 36 | "title": "Start coding!" 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Features from '../components/features'; 3 | import HowTo from '../components/how-to'; 4 | import Layout from '../components/layout'; 5 | 6 | const IndexPage = () => ( 7 | 8 |
9 | 10 | 11 |
12 |
13 | ); 14 | 15 | export default IndexPage; 16 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PrototypeInteractive/gatsby-react-boilerplate/7ae4341626d11f9a45898828591ba7038201b920/static/.gitkeep --------------------------------------------------------------------------------