├── .vscode ├── extensions.json ├── settings.json └── tasks.json ├── LICENSE ├── README.md ├── api ├── .gitignore ├── config.toml ├── content │ ├── coaches │ │ ├── all.md │ │ └── retired.md │ └── players │ │ ├── all.md │ │ └── retail.md ├── data │ └── MLB.toml ├── layouts │ ├── _default │ │ └── single.json │ └── shortcodes │ │ ├── coaches.html │ │ ├── json-data.html │ │ └── players.html ├── package.json └── static │ ├── _headers │ ├── _redirects │ ├── asset │ ├── bartolo-colon-2017.jpg │ ├── dustybobble2016.jpg │ ├── johnsonbobble2013.jpg │ ├── ra-dickey-2014.jpg │ ├── trea-turner-mlb-retail.jpg │ └── trea-turner-sga-2017.jpg │ ├── favicon.ico │ └── index.html ├── app ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── README.md ├── assets │ └── README.md ├── components │ ├── Logo.vue │ ├── README.md │ ├── SimpleTabularData.vue │ └── VuetifyLogo.vue ├── layouts │ ├── README.md │ └── default.vue ├── middleware │ └── README.md ├── nuxt.config.js ├── package-lock.json ├── package.json ├── pages │ ├── README.md │ ├── coaches.vue │ ├── index.vue │ └── players.vue ├── plugins │ ├── README.md │ └── vuetify.js ├── static │ ├── README.md │ ├── _redirects │ ├── favicon.ico │ └── v.png ├── store │ └── README.md └── yarn.lock ├── netlify.toml └── package.json /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "casualjim.gotemplate", 4 | "bungcip.better-toml", 5 | "octref.vetur" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.insertFinalNewline": false, 3 | "files.exclude": { 4 | "**/.git": true, 5 | "**/.svn": true, 6 | "**/.hg": true, 7 | "**/CVS": true, 8 | "**/.DS_Store": true, 9 | "bin": true, 10 | "node_modules": true, 11 | "dist": false 12 | }, 13 | "files.associations": { 14 | "**/layouts/**/*.html": "gohtml", 15 | "**/layouts/**/*.json": "gotemplate" 16 | }, 17 | "autorun.build": false 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "all:dev", 8 | "dependsOn": [ 9 | "api:dev", 10 | "app:dev" 11 | ], 12 | "problemMatcher": [] 13 | }, 14 | { 15 | "label": "api:dev", 16 | "type": "shell", 17 | "command": "npm run dev", 18 | "options": { 19 | "cwd": "api/", 20 | "shell": { 21 | "executable": "cmd.exe", 22 | "args": [ 23 | "/K" 24 | ] 25 | } 26 | }, 27 | "isBackground": true, 28 | "problemMatcher": [], 29 | "presentation": { 30 | "reveal": "always", 31 | "panel": "dedicated" 32 | } 33 | }, 34 | { 35 | "label": "app:dev", 36 | "type": "shell", 37 | "command": "npm run dev", 38 | "options": { 39 | "cwd": "app/", 40 | "shell": { 41 | "executable": "cmd.exe", 42 | "args": [ 43 | "/K" 44 | ] 45 | } 46 | }, 47 | "isBackground": true, 48 | "problemMatcher": [], 49 | "presentation": { 50 | "reveal": "always", 51 | "panel": "dedicated" 52 | } 53 | } 54 | ] 55 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Steve Lathrop 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 | # Research Project - JAMstack SPA and REST API Using Vue, Hugo, and Netlify CMS 2 | 3 | This repo contains a demo/POC project to see how well a monorepo using Vue, Hugo, and Netlify will work. 4 | 5 | The idea is to use Hugo to generate a read-only, git-backed REST API (inspiration was found [here](https://forestry.io/blog/build-a-json-api-with-hugo/)) with data that can be updated via: 6 | 7 | 1. A Netlify CMS admin UI, or 8 | 1. The GitHub API (which effectively makes the API read-write, with a bit of build latency) 9 | 10 | The API backend would, for purposes of this demo, be hit by a Vue.js, Nuxt, Axios, Vuetify SPA front-end. 11 | 12 | And the hope is to have all of the pieces in this one monorepo deploy via Netlify upon any push to master (see related discussion [here](https://github.com/netlify/netlify-cms/issues/1325)). 13 | 14 | So to summarize: 15 | 16 | - **App**: Vue.js SPA 17 | - **API**: Hugo-generated read-only (as of latest build) JSON. Being git-backed, the GitHub API effectively makes it read-write 18 | - **Admin**: Netlify CMS (React) front-end for non-technical content editors to add, edit, and delete data 19 | 20 | And given the JAMstack model and Netlify's hosting, this should all be massively scalable, globally distributed via CDN, extremely fast, virtually un-hackable, and totally free to run. 21 | 22 | ## How This Project Was Initially Created 23 | 24 | Here's a running list of the things that I did to kick-off this project after writing the initial README content above. 25 | 26 | ### Tooling 27 | 28 | I already had the tools installed, but if you want to follow along here's what you need. 29 | 30 | - This project assumes that you have [installed a recent **Node.js** LTS](https://nodejs.org/en/download/) version 31 | - This project also assumes that you have [installed **Hugo**](https://gohugo.io/getting-started/installing) and that it is globally available to run from the command prompt 32 | - Optionally [install **Yarn**](https://yarnpkg.com/en/docs/install) if you wish to use it instead of NPM 33 | - I use Visual Studio Code ([**VSCode**](https://code.visualstudio.com/download)) 34 | 35 | ### API 36 | 37 | For the API piece it's about getting Hugo setup for serving primarily JSON instead of HTML. 38 | 39 |
Details 40 | 41 | - From the root folder, I ran `hugo new site api`, which created the `api` subfolder 42 | - In the `api` folder 43 | - Cleaned a bit, removing Hugo stuff we won't need: `archetypes`, `themes`, etc. 44 | - Tweaked Hugo's `config.toml` to eliminate RSS and sitemap stuff 45 | - Ran `npm init -y` to create an initial `package.json` so we can use NPM Scripts to control how Hugo does things 46 | - NPM Scripts configured to support commands: 47 | - `npm run dev` or `yarn dev` to run a local Hugo development server with live reload 48 | - `npm run build` or `yarn build` to do a quick, incremental build to `./dist` 49 | - `npm run build-full` or `yarn build-full` to do a full build, cleaning the `./dist` folder 50 | - Logged-in to [app.netlify.com](https://app.netlify.com) with my GitHub credentials and clicked "New site from Git" 51 | - Under "Continuous Deployment" selected GitHub and then clicked "Authorize netlify" 52 | - Under "Create a new site" selected this repo 53 | - Configured `master` branch to deploy, set "Build command" to `cd api && npm run build` and "Publish directory" to `api/dist` 54 | - Clicked "Deploy site" 55 | - Configured subdomain so that site is hosted under Netlify at: https://bobble-api.netlify.com/ 56 | - Please see NOTE in `netlify.toml` config file RE: setup as it is unique to this monorepo approach 57 | 58 |
59 | 60 | ### App 61 | 62 | For the frontend App I used [**create-nuxt-app**](https://github.com/nuxt-community/create-nuxt-app). 63 | 64 |
Details 65 | 66 | - From this project's root folder, I ran `yarn create nuxt-app app` and entered/selected the following options 67 | - Project name: `slathrop-vue-hugo-spa-app` 68 | - Project description: Demo Vue Hugo SPA App 69 | - Use a custom server framework: none 70 | - Use a custom UI framework: vuetify 71 | - Choose rendering mode: Single Page App 72 | - Use axios module: yes 73 | - Use eslint: yes 74 | - Choose a package manager: npm 75 | - `create-nuxt-app` initializes git in the `app` folder created. We don't need separate git tracking for this subfolder, so 76 | - Changed directory into *app*: `cd app` 77 | - Removed `.git` folder: `rd /s /q .git` (on Windows) 78 | - `create-nuxt-app` has some outdated dependencies listed in the generated `package.json`, so updated to 79 | - `"nuxt": "^1.4.0"` 80 | - `"vuetify": "^1.0.18"` 81 | - `"@nuxtjs/axios": "^5.3.1"` 82 | - Ran `npm install` 83 | - Changed the default app component style from `dark` to `light` in `app\layouts\default.vue` and the default progress bar color in `app\nuxt.config.js` 84 | - Logged-in to [app.netlify.com](https://app.netlify.com) with my GitHub credentials and clicked "New site from Git" 85 | - Under "Continuous Deployment" selected GitHub and then clicked "Authorize netlify" 86 | - Under "Create a new site" selected this repo 87 | - Configured `master` branch to deploy, set "Build command" to `cd app && npm install && npm run generate` and "Publish directory" to `app/dist` 88 | - Clicked "Deploy site" 89 | - Configured subdomain so that site is hosted under Netlify at: https://bobble-app.netlify.com/ 90 | 91 |
92 | 93 | ### Admin 94 | 95 | For the admin UI: 96 | 97 | - Netlify CMS 98 | - TODO 99 | 100 | ## Implementation 101 | 102 | TODO 103 | -------------------------------------------------------------------------------- /api/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | 4 | # logs 5 | *.log 6 | 7 | # Hugo destination dir 8 | dist 9 | -------------------------------------------------------------------------------- /api/config.toml: -------------------------------------------------------------------------------- 1 | baseURL = "/" 2 | languageCode = "en-us" 3 | title = "Hugo REST API Demo" 4 | disableKinds = ["RSS", "sitemap", "taxonomy", "taxonomyTerm", "home", "section"] 5 | 6 | [outputFormats.JSON] 7 | baseName = "get" 8 | isPlainText = true 9 | isHTML = false 10 | noUgly = false 11 | 12 | [outputFormats.JSON.mediaType] 13 | delimiter = "." 14 | type = "application/json" 15 | string = "application/json+json" 16 | mainType = "application" 17 | subType = "json" 18 | suffix = "json" 19 | -------------------------------------------------------------------------------- /api/content/coaches/all.md: -------------------------------------------------------------------------------- 1 | +++ 2 | outputs = ['JSON'] 3 | +++ 4 | {{< json-data >}} 5 | {{< coaches >}} 6 | {{< /json-data >}} -------------------------------------------------------------------------------- /api/content/coaches/retired.md: -------------------------------------------------------------------------------- 1 | +++ 2 | outputs = ['JSON'] 3 | +++ 4 | {{< json-data >}} 5 | {{< coaches subcat="Retired" >}} 6 | {{< /json-data >}} -------------------------------------------------------------------------------- /api/content/players/all.md: -------------------------------------------------------------------------------- 1 | +++ 2 | outputs = ['JSON'] 3 | +++ 4 | {{< json-data >}} 5 | {{< players >}} 6 | {{< /json-data >}} -------------------------------------------------------------------------------- /api/content/players/retail.md: -------------------------------------------------------------------------------- 1 | +++ 2 | outputs = ['JSON'] 3 | +++ 4 | {{< json-data >}} 5 | {{< players subcat="Retail" >}} 6 | {{< /json-data >}} -------------------------------------------------------------------------------- /api/data/MLB.toml: -------------------------------------------------------------------------------- 1 | [[Bobble]] 2 | Key = 'Turner_Trea_2017_SGA' 3 | FirstName = 'Trea' 4 | LastName = 'Turner' 5 | Category = ['Player', 'SGA', '2017'] 6 | Team = 'Nationals' 7 | Pose = 'Sliding' 8 | Photo = '/asset/trea-turner-sga-2017.jpg' 9 | 10 | [[Bobble]] 11 | Key = 'Turner_Trea_MLB_Baller' 12 | FirstName = 'Trea' 13 | LastName = 'Turner' 14 | Category = ['Player', 'Licensed', 'Retail'] 15 | Team = 'Nationals' 16 | Pose = 'Hitting' 17 | Photo = '/asset/trea-turner-mlb-retail.jpg' 18 | 19 | [[Bobble]] 20 | Key = 'Colon_Bartolo_2017_SGA' 21 | FirstName = 'Bartolo' 22 | LastName = 'Colon' 23 | Category = ['Player', 'SGA', '2017'] 24 | Team = 'Braves' 25 | Pose = 'Pitching' 26 | Photo = '/asset/bartolo-colon-2017.jpg' 27 | 28 | [[Bobble]] 29 | Key = 'Dickey_RA_2014_SGA' 30 | FirstName = 'R.A.' 31 | LastName = 'Dickey' 32 | Category = ['Player', 'SGA', '2014'] 33 | Team = 'Blue Jays' 34 | Pose = 'Pitching' 35 | Photo = '/asset/ra-dickey-2014.jpg' 36 | 37 | [[Bobble]] 38 | Key = 'Baker_Dusty_2016_SGA' 39 | FirstName = 'Dusty' 40 | LastName = 'Baker' 41 | Category = ['Coach', 'SGA'] 42 | Team = 'Nationals' 43 | Pose = 'Standing' 44 | Photo = '/asset/dustybobble2016.jpg' 45 | 46 | [[Bobble]] 47 | Key = 'Johnson_Davey_2013_SGA' 48 | FirstName = 'Davy' 49 | LastName = 'Johnson' 50 | Category = ['Coach', 'SGA', 'Retired'] 51 | Team = 'Nationals' 52 | Pose = 'Standing' 53 | Photo = '/asset/johnsonbobble2013.jpg' 54 | 55 | # [[Bobble]] 56 | # Key = '' 57 | # FirstName = '' 58 | # LastName = '' 59 | # Category = ['Player/Coach', 'etc'], 60 | # Team = '' 61 | # Pose = '' 62 | # Photo = '/asset/image.jpg' 63 | -------------------------------------------------------------------------------- /api/layouts/_default/single.json: -------------------------------------------------------------------------------- 1 | {{/* 2 | For every individual (aka "single") markdown page, we simply render whatever 3 | content is specified in the body. In this case, the expectation is that the body 4 | is using Hugo shortcodes and templating to build a JSON response. 5 | */}} 6 | {{- .Content -}} -------------------------------------------------------------------------------- /api/layouts/shortcodes/coaches.html: -------------------------------------------------------------------------------- 1 | 8 | {{- $coaches := where .Site.Data.MLB.Bobble "Category" "intersect" (slice "Coach") -}} 9 | {{- $render := "coaches_render" -}} 10 | {{- $.Scratch.Set $render $coaches -}} 11 | 12 | {{- with .Get "subcat" -}} 13 | {{- $.Scratch.Set $render (where $coaches "Category" "intersect" (slice .)) -}} 14 | {{- end -}} 15 | 16 | { 17 | "coachBobbles": {{- $.Scratch.Get $render | jsonify }} 18 | } -------------------------------------------------------------------------------- /api/layouts/shortcodes/json-data.html: -------------------------------------------------------------------------------- 1 | 5 | { 6 | "data": {{- .Inner -}} 7 | } -------------------------------------------------------------------------------- /api/layouts/shortcodes/players.html: -------------------------------------------------------------------------------- 1 | 8 | {{- $players := where .Site.Data.MLB.Bobble "Category" "intersect" (slice "Player") -}} 9 | {{- $render := "players_render" -}} 10 | {{- $.Scratch.Set $render $players -}} 11 | 12 | {{- with .Get "subcat" -}} 13 | {{- $.Scratch.Set $render (where $players "Category" "intersect" (slice .)) -}} 14 | {{- end -}} 15 | 16 | { 17 | "playerBobbles": {{- $.Scratch.Get $render | jsonify }} 18 | } -------------------------------------------------------------------------------- /api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slathrop-hugo-api-demo", 3 | "version": "0.0.1", 4 | "description": "Hugo REST API Demo", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "hugo serve --disableFastRender", 8 | "build": "hugo -d ./dist", 9 | "build-full": "hugo -d ./dist --cleanDestinationDir", 10 | "build-preview": "hugo -d ./dist --buildDrafts --buildFuture" 11 | }, 12 | "keywords": [], 13 | "author": "slathrop", 14 | "license": "MIT" 15 | } -------------------------------------------------------------------------------- /api/static/_headers: -------------------------------------------------------------------------------- 1 | # API site allows CORS requests 2 | 3 | /* 4 | Access-Control-Allow-Origin: * -------------------------------------------------------------------------------- /api/static/_redirects: -------------------------------------------------------------------------------- 1 | # Rewrite API paths from cleaner folder names to underlying "get.json" files 2 | # TODO: Consider using Hugo's .Site.Pages and templates to render this automatically! 3 | 4 | /coaches/all /coaches/all/get.json 200 5 | /coaches/all/ /coaches/all/get.json 200 6 | 7 | /coaches/retired /coaches/retired/get.json 200 8 | /coaches/retired/ /coaches/retired/get.json 200 9 | 10 | /players/all /players/all/get.json 200 11 | /players/all/ /players/all/get.json 200 12 | 13 | /players/retail /players/retail/get.json 200 14 | /players/retail/ /players/retail/get.json 200 15 | -------------------------------------------------------------------------------- /api/static/asset/bartolo-colon-2017.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slathrop/vue-hugo-netlify-spa-demo/809894ddcbd031d313f3c1051782cca77f3dcd02/api/static/asset/bartolo-colon-2017.jpg -------------------------------------------------------------------------------- /api/static/asset/dustybobble2016.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slathrop/vue-hugo-netlify-spa-demo/809894ddcbd031d313f3c1051782cca77f3dcd02/api/static/asset/dustybobble2016.jpg -------------------------------------------------------------------------------- /api/static/asset/johnsonbobble2013.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slathrop/vue-hugo-netlify-spa-demo/809894ddcbd031d313f3c1051782cca77f3dcd02/api/static/asset/johnsonbobble2013.jpg -------------------------------------------------------------------------------- /api/static/asset/ra-dickey-2014.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slathrop/vue-hugo-netlify-spa-demo/809894ddcbd031d313f3c1051782cca77f3dcd02/api/static/asset/ra-dickey-2014.jpg -------------------------------------------------------------------------------- /api/static/asset/trea-turner-mlb-retail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slathrop/vue-hugo-netlify-spa-demo/809894ddcbd031d313f3c1051782cca77f3dcd02/api/static/asset/trea-turner-mlb-retail.jpg -------------------------------------------------------------------------------- /api/static/asset/trea-turner-sga-2017.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slathrop/vue-hugo-netlify-spa-demo/809894ddcbd031d313f3c1051782cca77f3dcd02/api/static/asset/trea-turner-sga-2017.jpg -------------------------------------------------------------------------------- /api/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slathrop/vue-hugo-netlify-spa-demo/809894ddcbd031d313f3c1051782cca77f3dcd02/api/static/favicon.ico -------------------------------------------------------------------------------- /api/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Hugo REST API Demo 9 | 10 | 11 | 12 |

Running

13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/.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 | -------------------------------------------------------------------------------- /app/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | parserOptions: { 8 | parser: 'babel-eslint' 9 | }, 10 | extends: [ 11 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention 12 | 'plugin:vue/essential' 13 | ], 14 | // required to lint *.vue files 15 | plugins: [ 16 | 'vue' 17 | ], 18 | // add your custom rules here 19 | rules: {} 20 | } 21 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | 4 | # logs 5 | npm-debug.log 6 | 7 | # Nuxt build 8 | .nuxt 9 | 10 | # Nuxt generate 11 | dist 12 | -------------------------------------------------------------------------------- /app/README.md: -------------------------------------------------------------------------------- 1 | # Demo Vue Hugo SPA App 2 | 3 | ## Build Setup 4 | 5 | ``` bash 6 | # install dependencies 7 | $ yarn install 8 | 9 | # serve with hot reload at localhost:3000 10 | $ yarn run dev 11 | 12 | # build for production and launch server 13 | $ yarn run build 14 | $ yarn start 15 | 16 | # generate static project 17 | $ yarn run generate 18 | ``` 19 | 20 | For detailed explanation on how things work, checkout [Nuxt.js docs](https://nuxtjs.org). 21 | -------------------------------------------------------------------------------- /app/assets/README.md: -------------------------------------------------------------------------------- 1 | # ASSETS 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 un-compiled assets such as LESS, SASS, or JavaScript. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked). 8 | -------------------------------------------------------------------------------- /app/components/Logo.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 80 | -------------------------------------------------------------------------------- /app/components/README.md: -------------------------------------------------------------------------------- 1 | # COMPONENTS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | The components directory contains your Vue.js Components. 6 | 7 | _Nuxt.js doesn't supercharge these components._ 8 | -------------------------------------------------------------------------------- /app/components/SimpleTabularData.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 99 | 100 | 106 | -------------------------------------------------------------------------------- /app/components/VuetifyLogo.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 17 | -------------------------------------------------------------------------------- /app/layouts/README.md: -------------------------------------------------------------------------------- 1 | # LAYOUTS 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 Application Layouts. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts). 8 | -------------------------------------------------------------------------------- /app/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 64 | 65 | 71 | -------------------------------------------------------------------------------- /app/middleware/README.md: -------------------------------------------------------------------------------- 1 | # MIDDLEWARE 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 application middleware. 6 | The middleware lets you define custom function to be ran before rendering a page or a group of pages (layouts). 7 | 8 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware). 9 | -------------------------------------------------------------------------------- /app/nuxt.config.js: -------------------------------------------------------------------------------- 1 | const pkg = require('./package') 2 | 3 | const nodeExternals = require('webpack-node-externals') 4 | 5 | module.exports = { 6 | mode: 'spa', 7 | 8 | /* 9 | ** Headers of the page 10 | */ 11 | head: { 12 | title: 'MLB Bobbleheads', // pkg.name, 13 | meta: [{ 14 | charset: 'utf-8' 15 | }, 16 | { 17 | name: 'viewport', 18 | content: 'width=device-width, initial-scale=1' 19 | }, 20 | { 21 | hid: 'description', 22 | name: 'description', 23 | content: pkg.description 24 | } 25 | ], 26 | link: [{ 27 | rel: 'icon', 28 | type: 'image/x-icon', 29 | href: '/favicon.ico' 30 | }, 31 | { 32 | rel: 'stylesheet', 33 | href: 'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' 34 | } 35 | ] 36 | }, 37 | 38 | /* 39 | ** Customize the progress-bar color 40 | */ 41 | loading: { 42 | color: '#212121' 43 | }, 44 | 45 | /* 46 | ** Global CSS 47 | */ 48 | css: [ 49 | 'vuetify/src/stylus/main.styl' 50 | ], 51 | 52 | /* 53 | ** Plugins to load before mounting the App 54 | */ 55 | plugins: [ 56 | '@/plugins/vuetify' 57 | ], 58 | 59 | /* 60 | ** Nuxt.js modules 61 | */ 62 | modules: [ 63 | // Doc: https://github.com/nuxt-community/axios-module#usage 64 | '@nuxtjs/axios' 65 | ], 66 | /* 67 | ** Axios module configuration 68 | */ 69 | axios: { 70 | // See https://github.com/nuxt-community/axios-module#options 71 | // https: true 72 | debug: true, 73 | proxyHeaders: false, 74 | headers: { 75 | common: {}, 76 | delete: {}, 77 | get: {}, 78 | head: {}, 79 | post: {}, 80 | put: {}, 81 | patch: {} 82 | } 83 | }, 84 | 85 | /* 86 | ** Build configuration 87 | */ 88 | build: { 89 | /* 90 | ** You can extend webpack config here 91 | */ 92 | extend(config, ctx) { 93 | // Run ESLint on save 94 | if (ctx.isDev && ctx.isClient) { 95 | config.module.rules.push({ 96 | enforce: 'pre', 97 | test: /\.(js|vue)$/, 98 | loader: 'eslint-loader', 99 | exclude: /(node_modules)/ 100 | }) 101 | } 102 | if (ctx.isServer) { 103 | config.externals = [ 104 | nodeExternals({ 105 | whitelist: [/^vuetify/] 106 | }) 107 | ] 108 | } 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slathrop-vue-hugo-spa-app", 3 | "version": "0.0.2", 4 | "description": "Demo Vue Hugo SPA App", 5 | "author": "SLathrop", 6 | "private": true, 7 | "scripts": { 8 | "dev": "nuxt", 9 | "build": "nuxt build", 10 | "start": "nuxt start", 11 | "generate": "nuxt generate", 12 | "lint": "eslint --ext .js,.vue --ignore-path .gitignore .", 13 | "precommit": "npm run lint" 14 | }, 15 | "dependencies": { 16 | "@nuxtjs/axios": "^5.13.6", 17 | "ajv": "^6.5.0", 18 | "nuxt": "^1.4.5", 19 | "vuetify": "^1.0.18" 20 | }, 21 | "devDependencies": { 22 | "cross-env": "^5.0.1", 23 | "babel-eslint": "^8.2.3", 24 | "eslint": "^4.19.1", 25 | "eslint-loader": "^2.0.0", 26 | "eslint-plugin-vue": "^4.5.0", 27 | "stylus": "^0.54.5", 28 | "stylus-loader": "^3.0.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/pages/README.md: -------------------------------------------------------------------------------- 1 | # PAGES 2 | 3 | This directory contains your Application Views and Routes. 4 | The framework reads all the `*.vue` files inside this directory and create the router of your application. 5 | 6 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing). 7 | -------------------------------------------------------------------------------- /app/pages/coaches.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 28 | -------------------------------------------------------------------------------- /app/pages/index.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 44 | -------------------------------------------------------------------------------- /app/pages/players.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 28 | -------------------------------------------------------------------------------- /app/plugins/README.md: -------------------------------------------------------------------------------- 1 | # PLUGINS 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 Javascript plugins that you want to run before mounting the root Vue.js application. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins). 8 | -------------------------------------------------------------------------------- /app/plugins/vuetify.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuetify from 'vuetify' 3 | import colors from 'vuetify/es5/util/colors' 4 | 5 | Vue.use(Vuetify, { 6 | theme: { 7 | primary: '#121212', // a color that is not in the material colors palette 8 | accent: colors.grey.darken3, 9 | secondary: colors.amber.darken3, 10 | info: colors.teal.lighten1, 11 | warning: colors.amber.base, 12 | error: colors.deepOrange.accent4, 13 | success: colors.green.accent3 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /app/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 | 8 | Example: `/static/robots.txt` is mapped as `/robots.txt`. 9 | 10 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static). 11 | -------------------------------------------------------------------------------- /app/static/_redirects: -------------------------------------------------------------------------------- 1 | /api/* https://bobble-api.netlify.app/:splat 200 2 | -------------------------------------------------------------------------------- /app/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slathrop/vue-hugo-netlify-spa-demo/809894ddcbd031d313f3c1051782cca77f3dcd02/app/static/favicon.ico -------------------------------------------------------------------------------- /app/static/v.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slathrop/vue-hugo-netlify-spa-demo/809894ddcbd031d313f3c1051782cca77f3dcd02/app/static/v.png -------------------------------------------------------------------------------- /app/store/README.md: -------------------------------------------------------------------------------- 1 | # STORE 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 Vuex Store files. 6 | Vuex Store option is implemented in the Nuxt.js framework. 7 | 8 | Creating a file in this directory activate the option in the framework automatically. 9 | 10 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store). 11 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | # NOTE: 2 | # Ordinarily you might want to configure your Netlify "Build command" and 3 | # "Publish directory" in this file. But this project contains multiple sites, which 4 | # means that a single "netlify.toml" file won't work to accommodate the build commands 5 | # and publish directories for them all. 6 | # 7 | # Instead, use the Netlify website to enter those details for your sites individually. 8 | # For more info on this approach, see: 9 | # 10 | # https://github.com/netlify/netlify-cms/issues/1325 11 | # 12 | # You *can* however place common Build environment variables in this file. And you 13 | # can still use "_redirects" files in each individual site to configure redirects and 14 | # proxying as needed. 15 | 16 | [build.environment] 17 | NODE_VERSION = '10.13.0' 18 | HUGO_VERSION = '0.67.0' 19 | 20 | [[headers]] 21 | # Define which paths this specific [[headers]] block will cover 22 | for = "/*" 23 | [headers.values] 24 | Access-Control-Allow-Origin = "*" 25 | Access-Control-Allow-Headers = "X-Requested-With, Content-Type, Authorization, Origin, Accept" 26 | Access-Control-Allow-Methods = "GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH" 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-hugo-netlify-spa-demo", 3 | "version": "0.0.1", 4 | "description": "This repo contains a demo/POC project to see how well a monorepo using Vue, Hugo, and Netlify will work.", 5 | "main": "index.js", 6 | "scripts": { 7 | "api-dev": "hugo serve -s ./api --disableFastRender", 8 | "api-build": "hugo -s ./api -d ./dist", 9 | "api-build-full": "hugo -s ./api -d ./dist --cleanDestinationDir", 10 | "api-build-preview": "hugo -s ./api -d ./dist --buildDrafts --buildFuture" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/slathrop/vue-hugo-netlify-spa-demo.git" 15 | }, 16 | "keywords": [], 17 | "author": "SLathrop", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/slathrop/vue-hugo-netlify-spa-demo/issues" 21 | }, 22 | "homepage": "https://github.com/slathrop/vue-hugo-netlify-spa-demo#readme" 23 | } --------------------------------------------------------------------------------