├── .prettierrc ├── scripts ├── object-type.json ├── objects.json └── import.js ├── .gitignore ├── gatsby-browser.js ├── gatsby-ssr.js ├── src ├── components │ ├── header.js │ ├── nav.js │ ├── footer.js │ ├── index.css │ └── layout.js ├── pages │ └── not-found.js └── templates │ └── page.js ├── .eslintrc.js ├── gatsby-config.js ├── README.md ├── package.json ├── LICENSE └── gatsby-node.js /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "trailingComma": "es5" 5 | } 6 | -------------------------------------------------------------------------------- /scripts/object-type.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Pages", 3 | "slug": "pages", 4 | "singular": "page" 5 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project dependencies 2 | .cache 3 | node_modules 4 | yarn-error.log 5 | 6 | # Build directory 7 | /public 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /gatsby-browser.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's Browser APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/browser-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /src/components/header.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'gatsby' 3 | 4 | const Header = ({ siteTitle }) => ( 5 |
6 |

7 | 8 | {siteTitle} 9 |

10 |
11 | ) 12 | 13 | export default Header 14 | -------------------------------------------------------------------------------- /src/components/nav.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Link from 'gatsby-link' 3 | 4 | const Nav = ({ nav }) => ( 5 | 14 | ) 15 | 16 | export default Nav 17 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | }, 6 | "plugins": [ 7 | "react", 8 | ], 9 | "globals": { 10 | "graphql": false, 11 | }, 12 | "parserOptions": { 13 | "ecmaVersion": 8, 14 | "sourceType": "module", 15 | "ecmaFeatures": { 16 | "experimentalObjectRestSpread": true, 17 | "jsx": true, 18 | }, 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/components/footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Footer = () => ( 4 |
5 | © 6 | {new Date().getFullYear()} Cosmic JS{' '} 7 | Gatsby Starter.{' '} 8 | 9 | View the code 10 | 11 | . 12 |
13 | ) 14 | 15 | export default Footer 16 | -------------------------------------------------------------------------------- /scripts/objects.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "Home", 4 | "slug": "home", 5 | "content": "This is the home page content.", 6 | "type_slug": "pages" 7 | }, 8 | { 9 | "title": "About", 10 | "slug": "about", 11 | "content": "This is the about page content.", 12 | "type_slug": "pages" 13 | }, 14 | { 15 | "title": "Contact", 16 | "slug": "contact", 17 | "content": "This is the contact page content.", 18 | "type_slug": "pages" 19 | } 20 | ] -------------------------------------------------------------------------------- /src/pages/not-found.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Helmet from 'react-helmet' 3 | import Layout from '../components/layout' 4 | 5 | const NotFoundPage = () => ( 6 | 7 | 8 |

404 Page Not Found

9 |
10 | Oops! The content you are looking for does not exist in your Cosmic JS 11 | Bucket. 12 |
13 |
14 | ) 15 | 16 | export default NotFoundPage 17 | -------------------------------------------------------------------------------- /src/components/index.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-family: sans-serif; 3 | } 4 | body { 5 | margin: 0; 6 | padding: 0; 7 | } 8 | .main, .footer { 9 | padding: 0 20px 20px; 10 | max-width: 960px; 11 | margin: 0 auto; 12 | } 13 | .hero { 14 | background: #29ABE2; 15 | width: 100%; 16 | } 17 | .hero h1 { 18 | margin: 0; 19 | font-size: 30px; 20 | padding: 30px; 21 | max-width: 960px; 22 | margin: 0 auto; 23 | } 24 | .hero h1 a { 25 | color: #fff; 26 | text-decoration: none; 27 | } -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | siteMetadata: { 3 | title: 'Cosmic JS Gatsby Starter', 4 | nav: [{ slug: '/', name: 'Home' }, 5 | { slug: '/about', name: 'About' }, 6 | { slug: '/contact', name: 'Contact' }, 7 | { slug: '/not-found', name: 'Not Found' }, 8 | ] 9 | }, 10 | plugins: [ 11 | 'gatsby-plugin-react-helmet', 12 | { 13 | resolve: `gatsby-source-cosmicjs`, 14 | options: { 15 | bucketSlug: process.env.COSMIC_BUCKET || `node-starter`, 16 | objectTypes: [`pages`], 17 | // If you have enabled read_key to fetch data (optional). 18 | apiAccess: { 19 | read_key: process.env.COSMIC_READ_KEY || ``, 20 | } 21 | } 22 | }, 23 | ], 24 | } 25 | -------------------------------------------------------------------------------- /scripts/import.js: -------------------------------------------------------------------------------- 1 | const Cosmic = require('cosmicjs') 2 | const api = Cosmic() 3 | const COSMIC_BUCKET = process.env.COSMIC_BUCKET || 'node-starter' 4 | const bucket = api.bucket({ 5 | slug: COSMIC_BUCKET, 6 | read_key: process.env.COSMIC_READ_KEY, 7 | write_key: process.env.COSMIC_WRITE_KEY 8 | }) 9 | const default_objects = require('./objects') 10 | const default_object_type = require('./object-type') 11 | const importObjects = async () => { 12 | try { 13 | const res = await bucket.getObjects() 14 | if(res.status === 'empty') { 15 | bucket.addObjectType(default_object_type) 16 | default_objects.forEach(object => { 17 | bucket.addObject(object) 18 | }) 19 | } 20 | } catch (e) { 21 | console.log(e) 22 | } 23 | } 24 | importObjects() 25 | -------------------------------------------------------------------------------- /src/templates/page.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Helmet from 'react-helmet' 3 | import { graphql } from 'gatsby' 4 | import Layout from '../components/layout' 5 | 6 | class PageTemplate extends React.Component { 7 | render() { 8 | const page = this.props.data.cosmicjsPages 9 | return ( 10 | 11 | {page && ( 12 |
13 | 14 |

{page.title}

15 |
16 |
17 | )} 18 | 19 | ) 20 | } 21 | } 22 | 23 | export default PageTemplate 24 | 25 | export const pageQuery = graphql` 26 | query PageBySlug($slug: String!) { 27 | cosmicjsPages(slug: { eq: $slug }) { 28 | title 29 | content 30 | } 31 | } 32 | ` 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gatsby Starter 2 | Gatsby starter app powered by [Cosmic JS](https://cosmicjs.com) 🚀 Uses the [Official Cosmic JS Source Plugin for Gatsby](https://www.npmjs.com/package/gatsby-source-cosmicjs). 3 | 4 | ## Installation 5 | Option 1: Download code. Connects to demo Bucket. 6 | ```bash 7 | git clone https://github.com/cosmicjs/gatsby-starter 8 | cd gatsby-starter 9 | npm install 10 | npm run develop 11 | ``` 12 | 13 | Option 2: Download via the [Cosmic CLI](https://github.com/cosmicjs/cosmic-cli). Installs demo content and connects to your Cosmic JS Bucket. 14 | ```bash 15 | npm i -g cosmic-cli 16 | 17 | # Login to your Cosmic JS account 18 | cosmic login 19 | 20 | # Installs example content to a new or existing Bucket and downloads the app locally 21 | cosmic init gatsby-starter 22 | cd gatsby-starter 23 | cosmic start 24 | ``` 25 | ## [Gatsby CMS](https://cosmicjs.com/knowledge-base/gatsby-cms) 26 | Cosmic JS offers a [Headless CMS](https://cosmicjs.com/headless-cms) for your Gatsby websites and apps. 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-starter", 3 | "description": "Cosmic JS Gatsby Starter", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "cosmicjs": "^3.2.8", 7 | "gatsby": "^2.15.28", 8 | "gatsby-plugin-react-helmet": "^3.0.0", 9 | "gatsby-source-cosmicjs": "^1.0.3", 10 | "lodash": "^4.17.11", 11 | "react": "^16.9.0", 12 | "react-dom": "^16.9.0", 13 | "react-helmet": "^5.2.0" 14 | }, 15 | "license": "MIT", 16 | "scripts": { 17 | "start": "gatsby build; gatsby serve --port $PORT", 18 | "build": "gatsby build", 19 | "develop": "gatsby develop --port $PORT", 20 | "lint": "./node_modules/.bin/eslint --ext .js,.jsx --ignore-pattern public .", 21 | "format": "prettier --write 'src/**/*.js'", 22 | "import": "node ./scripts/import.js", 23 | "test": "echo \"Error: no test specified\" && exit 1" 24 | }, 25 | "devDependencies": { 26 | "eslint": "^4.19.1", 27 | "eslint-plugin-react": "^7.11.1", 28 | "prettier": "^1.14.3" 29 | }, 30 | "repository": { 31 | "type": "git", 32 | "url": "https://github.com/cosmicjs/gatsby-starter" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /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/components/layout.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Helmet from 'react-helmet' 3 | import { StaticQuery, graphql } from 'gatsby' 4 | 5 | import Header from './header' 6 | import Nav from './nav' 7 | import Footer from './footer' 8 | import './index.css' 9 | 10 | export default ({ children }) => ( 11 | { 26 | const siteTitle = data.site.siteMetadata.title 27 | const siteNav = data.site.siteMetadata.nav 28 | return ( 29 |
30 | 36 |
37 |
38 | {children} 39 |
41 |
43 | ) 44 | }} 45 | /> 46 | ) 47 | -------------------------------------------------------------------------------- /gatsby-node.js: -------------------------------------------------------------------------------- 1 | const each = require('lodash/each') 2 | const find = require('lodash/find') 3 | const path = require('path') 4 | 5 | exports.createPages = ({ graphql, actions }) => { 6 | const { createPage } = actions 7 | 8 | return new Promise((resolve, reject) => { 9 | const pageTemplate = path.resolve('./src/templates/page.js') 10 | resolve( 11 | graphql( 12 | ` 13 | { 14 | site{ 15 | siteMetadata{ 16 | nav{ 17 | slug 18 | name 19 | } 20 | } 21 | } 22 | allCosmicjsPages{ 23 | edges{ 24 | node{ 25 | slug 26 | } 27 | } 28 | } 29 | } 30 | ` 31 | ).then(result => { 32 | if (result.errors) { 33 | console.log(result.errors) 34 | reject(result.errors) 35 | } 36 | 37 | const navs = result.data.site.siteMetadata.nav; 38 | const pages = result.data.allCosmicjsPages.edges; 39 | 40 | each(navs, (page, index) => { 41 | const $slug = (page.slug === '/') ? 'home' : page.slug.slice(1); 42 | if(find(pages, function(o) { return o.node.slug === $slug })) { 43 | createPage({ 44 | path: `${page.slug}`, 45 | component: pageTemplate, 46 | context: { 47 | slug: $slug, 48 | }, 49 | }) 50 | } 51 | }) 52 | }) 53 | ) 54 | }) 55 | } --------------------------------------------------------------------------------