├── .editorconfig ├── .gitignore ├── README.md ├── assets ├── footer-bk.jpg └── header-bk.jpg ├── components └── AppFooter.vue ├── css └── main.scss ├── layouts └── default.vue ├── netlify.toml ├── nuxt.config.js ├── package.json ├── pages ├── _slug.vue └── index.vue ├── plugins ├── contentful.js └── posts.js ├── static ├── README.md ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico └── site.webmanifest ├── store └── index.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | /logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE / Editor 81 | .idea 82 | 83 | # Service worker 84 | sw.* 85 | 86 | # macOS 87 | .DS_Store 88 | 89 | # Vim swap files 90 | *.swp 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Contentful Nuxt Example Blog 2 | 3 | > An example blog with Contentful CMS and Nuxt/Vue Deployed on Netlify 4 | 5 | Set up example instructions [in this blog post](https://www.netlify.com/blog/2020/04/20/create-a-blog-with-contentful-and-nuxt/?utm_source=github&utm_medium=contentful-sd&utm_campaign=devex). You can also create a webhook with the [instructions in this post](https://www.netlify.com/blog/2020/04/24/automate-contentful-deploys-with-netlify-webhooks/?utm_source=github&utm_medium=webhooks-sd&utm_campaign=devex). 6 | 7 | ## Build Setup 8 | 9 | ```bash 10 | # install dependencies 11 | $ yarn install 12 | 13 | # serve with hot reload at localhost:3000 14 | $ yarn dev 15 | 16 | # build for production and launch server 17 | $ yarn build 18 | $ yarn start 19 | 20 | # generate static project 21 | $ yarn generate 22 | ``` 23 | 24 | For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org). 25 | -------------------------------------------------------------------------------- /assets/footer-bk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdras/contentful-nuxt-netlify/e80e6552eef812320a7bd2dd66ad3fa8ebf5f840/assets/footer-bk.jpg -------------------------------------------------------------------------------- /assets/header-bk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdras/contentful-nuxt-netlify/e80e6552eef812320a7bd2dd66ad3fa8ebf5f840/assets/header-bk.jpg -------------------------------------------------------------------------------- /components/AppFooter.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 17 | -------------------------------------------------------------------------------- /css/main.scss: -------------------------------------------------------------------------------- 1 | html { 2 | background: url(../assets/header-bk.jpg) no-repeat center top, #112545; 3 | background-size: 100% auto; 4 | font-family: "Baloo Paaji 2", -apple-system, BlinkMacSystemFont, "Segoe UI", 5 | Roboto, "Helvetica Neue", Arial, sans-serif; 6 | font-size: 18px; 7 | word-spacing: 1px; 8 | -ms-text-size-adjust: 100%; 9 | -webkit-text-size-adjust: 100%; 10 | -moz-osx-font-smoothing: grayscale; 11 | -webkit-font-smoothing: antialiased; 12 | box-sizing: border-box; 13 | color: #bcc0cc; 14 | } 15 | 16 | *, 17 | *:before, 18 | *:after { 19 | box-sizing: border-box; 20 | margin: 0; 21 | } 22 | 23 | a, 24 | a:visited, 25 | a:active { 26 | text-decoration: none; 27 | color: #ed8367; 28 | } 29 | 30 | .container { 31 | margin: 0 auto; 32 | padding: 25vw 20px 100px; 33 | min-height: 100vh; 34 | max-width: 700px; 35 | } 36 | 37 | hr { 38 | border-color: #63567b; 39 | } 40 | 41 | h1, 42 | h2, 43 | h3 { 44 | font-weight: 500; 45 | margin-top: 30px; 46 | line-height: 1; 47 | } 48 | 49 | h1 { 50 | font-size: 55px; 51 | font-family: "Molle", cursive; 52 | text-shadow: 0 1px 0 #403c61, 0 2px 0 #403c61, 0 3px 0 #403c61, 53 | 0 4px 0 rgb(104, 81, 148), 0 5px 0 #55486d, 0 6px 1px rgba(0, 0, 0, 0.1), 54 | 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 55 | 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 56 | 0 10px 10px rgba(0, 0, 0, 0.2), 0 20px 20px rgba(0, 0, 0, 0.15); 57 | } 58 | 59 | p { 60 | margin-top: 15px; 61 | } 62 | 63 | .author { 64 | font-style: italic; 65 | color: #689aed; 66 | } 67 | 68 | .image { 69 | border-radius: 15px; 70 | border: 2px solid #04225f; 71 | box-shadow: 4px 4px 8px -2px rgba(0, 0, 0, 0.6); 72 | background-size: cover; 73 | } 74 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = "dist" 3 | command = "npm run generate" 4 | [build.environment] 5 | NODE_VERSION = "11" -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | dotenv.config(); 3 | 4 | const contentful = require("contentful"); 5 | const client = contentful.createClient({ 6 | space: process.env.CONTENTFUL_SPACE, 7 | accessToken: process.env.CONTENTFUL_ACCESSTOKEN 8 | }); 9 | 10 | export default { 11 | mode: "universal", 12 | /* 13 | ** Headers of the page 14 | */ 15 | head: { 16 | title: process.env.npm_package_name || "", 17 | meta: [ 18 | { charset: "utf-8" }, 19 | { name: "viewport", content: "width=device-width, initial-scale=1" }, 20 | { 21 | hid: "description", 22 | name: "description", 23 | content: process.env.npm_package_description || "" 24 | } 25 | ], 26 | link: [ 27 | { rel: "icon", type: "image/x-icon", href: "/favicon.ico" }, 28 | { 29 | rel: "stylesheet", 30 | href: 31 | "https://fonts.googleapis.com/css?family=Molle:400i|Baloo+Paaji+2:400,500&display=swap" 32 | } 33 | ] 34 | }, 35 | /* 36 | ** Customize the progress-bar color 37 | */ 38 | loading: { color: "#fff" }, 39 | /* 40 | ** Global CSS 41 | */ 42 | css: ["~/css/main.scss"], 43 | render: { 44 | bundleRenderer: { 45 | shouldPreload: (file, type) => { 46 | return ["script", "style", "font"].includes(type); 47 | } 48 | } 49 | }, 50 | /* 51 | ** Plugins to load before mounting the App 52 | */ 53 | plugins: ["~/plugins/contentful", "~/plugins/posts"], 54 | /* 55 | ** Environment variables 56 | */ 57 | env: { 58 | CONTENTFUL_SPACE: process.env.CONTENTFUL_SPACE, 59 | CONTENTFUL_ACCESSTOKEN: process.env.CONTENTFUL_ACCESSTOKEN, 60 | CONTENTFUL_ENVIRONMENT: process.env.CONTENTFUL_ENVIRONMENT 61 | }, 62 | modules: ["@nuxtjs/markdownit"], 63 | markdownit: { 64 | injected: true 65 | }, 66 | generate: { 67 | routes() { 68 | return Promise.all([ 69 | client.getEntries({ 70 | content_type: "blogPost" 71 | }) 72 | ]).then(([blogEntries]) => { 73 | return [...blogEntries.items.map(entry => entry.fields.slug)]; 74 | }); 75 | } 76 | } 77 | }; 78 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "megan-blog", 3 | "version": "1.0.0", 4 | "description": "Animal Crossing Blog by Megan", 5 | "author": "sdras", 6 | "private": true, 7 | "scripts": { 8 | "dev": "nuxt", 9 | "build": "nuxt build", 10 | "start": "nuxt start", 11 | "generate": "nuxt generate" 12 | }, 13 | "dependencies": { 14 | "@nuxtjs/markdownit": "^1.2.9", 15 | "contentful": "^7.14.2", 16 | "dotenv": "^8.2.0", 17 | "node-sass": "^4.13.1", 18 | "nuxt": "^2.0.0", 19 | "sass-loader": "^8.0.2" 20 | }, 21 | "devDependencies": {} 22 | } 23 | -------------------------------------------------------------------------------- /pages/_slug.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 39 | 40 | 52 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 37 | 38 | 77 | -------------------------------------------------------------------------------- /plugins/contentful.js: -------------------------------------------------------------------------------- 1 | const contentful = require("contentful"); 2 | 3 | module.exports = contentful.createClient({ 4 | space: process.env.CONTENTFUL_SPACE, 5 | accessToken: process.env.CONTENTFUL_ACCESSTOKEN 6 | }); 7 | -------------------------------------------------------------------------------- /plugins/posts.js: -------------------------------------------------------------------------------- 1 | export default async ({ store }) => { 2 | await store.dispatch("getPosts"); 3 | }; 4 | -------------------------------------------------------------------------------- /static/README.md: -------------------------------------------------------------------------------- 1 | # STATIC 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your static files. 6 | Each file inside this directory is mapped to `/`. 7 | Thus you'd want to delete this README.md before deploying to production. 8 | 9 | Example: `/static/robots.txt` is mapped as `/robots.txt`. 10 | 11 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static). 12 | -------------------------------------------------------------------------------- /static/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdras/contentful-nuxt-netlify/e80e6552eef812320a7bd2dd66ad3fa8ebf5f840/static/android-chrome-192x192.png -------------------------------------------------------------------------------- /static/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdras/contentful-nuxt-netlify/e80e6552eef812320a7bd2dd66ad3fa8ebf5f840/static/android-chrome-512x512.png -------------------------------------------------------------------------------- /static/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdras/contentful-nuxt-netlify/e80e6552eef812320a7bd2dd66ad3fa8ebf5f840/static/apple-touch-icon.png -------------------------------------------------------------------------------- /static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdras/contentful-nuxt-netlify/e80e6552eef812320a7bd2dd66ad3fa8ebf5f840/static/favicon-16x16.png -------------------------------------------------------------------------------- /static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdras/contentful-nuxt-netlify/e80e6552eef812320a7bd2dd66ad3fa8ebf5f840/static/favicon-32x32.png -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdras/contentful-nuxt-netlify/e80e6552eef812320a7bd2dd66ad3fa8ebf5f840/static/favicon.ico -------------------------------------------------------------------------------- /static/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- 1 | import client from "~/plugins/contentful"; 2 | 3 | export const state = () => ({ 4 | posts: null 5 | }); 6 | 7 | export const mutations = { 8 | updatePosts: (state, posts) => { 9 | state.posts = posts; 10 | } 11 | }; 12 | 13 | export const actions = { 14 | async getPosts({ commit }) { 15 | try { 16 | if (!client) return; 17 | const response = await client.getEntries({ 18 | content_type: "blogPost" 19 | }); 20 | if (response.items.length > 0) commit("updatePosts", response.items); 21 | } catch (err) { 22 | console.error(err); 23 | } 24 | } 25 | }; 26 | --------------------------------------------------------------------------------