├── starter ├── .env.example ├── src │ ├── components │ │ ├── README.md │ │ ├── RichText.vue │ │ ├── Navbar.vue │ │ ├── LargeMedia.vue │ │ ├── Slider.vue │ │ ├── Content.vue │ │ ├── ProjectCard.vue │ │ └── Footer.vue │ ├── layouts │ │ ├── README.md │ │ └── Default.vue │ ├── pages │ │ ├── README.md │ │ ├── About.vue │ │ └── Index.vue │ ├── templates │ │ ├── README.md │ │ └── Project.vue │ ├── utils │ │ ├── medias.js │ │ └── seo.js │ └── main.js ├── static │ └── README.md ├── README.md ├── package.json ├── tailwind.config.js ├── gridsome.config.js └── gridsome.server.js ├── starter.json ├── screenshot.png ├── LICENSE.txt ├── README.md └── .gitignore /starter/.env.example: -------------------------------------------------------------------------------- 1 | GRIDSOME_STRAPI_URL=http://localhost:1337 -------------------------------------------------------------------------------- /starter.json: -------------------------------------------------------------------------------- 1 | { 2 | "template": "https://github.com/strapi/strapi-template-portfolio" 3 | } 4 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strapi/strapi-starter-gridsome-portfolio/HEAD/screenshot.png -------------------------------------------------------------------------------- /starter/src/components/README.md: -------------------------------------------------------------------------------- 1 | Add components that will be imported to Pages and Layouts to this folder. 2 | Learn more about components here: https://gridsome.org/docs/components/ 3 | 4 | You can delete this file. 5 | -------------------------------------------------------------------------------- /starter/static/README.md: -------------------------------------------------------------------------------- 1 | Add static files here. Files in this directory will be copied directly to `dist` folder during build. For example, /static/robots.txt will be located at https://yoursite.com/robots.txt. 2 | 3 | This file should be deleted. -------------------------------------------------------------------------------- /starter/src/layouts/README.md: -------------------------------------------------------------------------------- 1 | Layout components are used to wrap pages and templates. Layouts should contain components like headers, footers or sidebars that will be used across the site. 2 | 3 | Learn more about Layouts: https://gridsome.org/docs/layouts/ 4 | 5 | You can delete this file. 6 | -------------------------------------------------------------------------------- /starter/src/pages/README.md: -------------------------------------------------------------------------------- 1 | Pages are usually used for normal pages or for listing items from a GraphQL collection. 2 | Add .vue files here to create pages. For example **About.vue** will be **site.com/about**. 3 | Learn more about pages: https://gridsome.org/docs/pages/ 4 | 5 | You can delete this file. 6 | -------------------------------------------------------------------------------- /starter/src/templates/README.md: -------------------------------------------------------------------------------- 1 | Templates for **GraphQL collections** should be added here. 2 | To create a template for a collection called `WordPressPost` 3 | create a file named `WordPressPost.vue` in this folder. 4 | 5 | Learn more: https://gridsome.org/docs/templates/ 6 | 7 | You can delete this file. 8 | -------------------------------------------------------------------------------- /starter/src/components/RichText.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /starter/src/utils/medias.js: -------------------------------------------------------------------------------- 1 | export function getStrapiMedia(url) { 2 | // Check if URL is a local path 3 | if (url.startsWith('/')) { 4 | // Prepend Strapi address 5 | const strapiUrl = process.env.GRIDSOME_STRAPI_URL || 'http://localhost:1337' 6 | return strapiUrl + url 7 | } 8 | // Otherwise return full URL 9 | return url 10 | } 11 | -------------------------------------------------------------------------------- /starter/src/main.js: -------------------------------------------------------------------------------- 1 | // This is the main.js file. Import global CSS and scripts here. 2 | // The Client API can be used here. Learn more: gridsome.org/docs/client-api 3 | 4 | import DefaultLayout from '~/layouts/Default.vue' 5 | 6 | export default function (Vue, { router, head, isClient }) { 7 | // Set default layout as a global component 8 | Vue.component('Layout', DefaultLayout) 9 | } 10 | -------------------------------------------------------------------------------- /starter/README.md: -------------------------------------------------------------------------------- 1 | # Gridsome frontend 2 | 3 | This is the frontend of the Strapi Starter Gridsome Portfolio. 4 | 5 | ## Commands 6 | 7 | **yarn develop** 8 | 9 | Creates a development server with hot reloading. 10 | 11 | **yarn explore** 12 | 13 | Loads a GraphQL Playground to explore the data layer. 14 | 15 | **yarn build** 16 | 17 | Creates a build optimized for production in the `/dist` folder. 18 | -------------------------------------------------------------------------------- /starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "front", 3 | "private": true, 4 | "scripts": { 5 | "build": "gridsome build", 6 | "develop": "gridsome develop", 7 | "explore": "gridsome explore" 8 | }, 9 | "dependencies": { 10 | "@gridsome/source-graphql": "^0.1.0", 11 | "@tailwindcss/typography": "^0.2.0", 12 | "babel-runtime": "^6.26.0", 13 | "gridsome": "^0.7.0", 14 | "gridsome-plugin-tailwindcss": "^3.0.1", 15 | "tailwindcss": "^1.6.2", 16 | "vue-markdown": "^2.2.4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /starter/src/components/Navbar.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | query { 16 | metadata { 17 | siteName 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /starter/tailwind.config.js: -------------------------------------------------------------------------------- 1 | const { colors } = require('tailwindcss/defaultTheme') 2 | 3 | module.exports = { 4 | purge: ['./src/**/*.vue'], 5 | theme: { 6 | extend: { 7 | colors: { 8 | ...colors, 9 | primary: colors.green, 10 | secondary: colors.blue, 11 | }, 12 | container: { 13 | center: true, 14 | padding: { 15 | default: '0.5rem', 16 | sm: '1rem', 17 | lg: '8rem', 18 | xl: '12rem', 19 | }, 20 | }, 21 | }, 22 | }, 23 | variants: {}, 24 | plugins: [ 25 | require('@tailwindcss/typography'), 26 | ], 27 | } 28 | -------------------------------------------------------------------------------- /starter/src/components/LargeMedia.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 25 | -------------------------------------------------------------------------------- /starter/gridsome.config.js: -------------------------------------------------------------------------------- 1 | // This is where project configuration and plugin options are located. 2 | // Learn more: https://gridsome.org/docs/config 3 | 4 | // Changes here require a server restart. 5 | // To restart press CTRL + C in terminal and run `gridsome develop` 6 | 7 | module.exports = { 8 | siteName: 'Strapi Gridsome Portfolio', 9 | siteDescription: 'A portfolio site made using Gridsome and Strapi', 10 | plugins: [ 11 | { 12 | use: '@gridsome/source-graphql', 13 | options: { 14 | url: (process.env.GRIDSOME_STRAPI_URL || "http://localhost:1337") + "/graphql", 15 | fieldName: 'strapi', 16 | typeName: 'strapiTypes' 17 | } 18 | }, 19 | { 20 | use: "gridsome-plugin-tailwindcss", 21 | } 22 | ], 23 | } 24 | -------------------------------------------------------------------------------- /starter/src/utils/seo.js: -------------------------------------------------------------------------------- 1 | export function getMetaTags(title, description, image) { 2 | return [ 3 | { 4 | key: 'twitter:card', 5 | name: 'twitter:card', 6 | content: 'summary_large_image', 7 | }, 8 | { 9 | key: 'og:title', 10 | property: 'og:title', 11 | content: title, 12 | }, 13 | { 14 | key: 'twitter:title', 15 | name: 'twitter:title', 16 | content: title, 17 | }, 18 | { 19 | key: 'og:description', 20 | property: 'og:description', 21 | content: description, 22 | }, 23 | { 24 | key: 'twitter:description', 25 | name: 'twitter:description', 26 | content: description, 27 | }, 28 | { 29 | key: 'og:image', 30 | property: 'og:image', 31 | content: image, 32 | }, 33 | { 34 | key: 'twitter:image', 35 | name: 'twitter:image', 36 | content: image, 37 | }, 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /starter/src/components/Slider.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 33 | -------------------------------------------------------------------------------- /starter/src/components/Content.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [year] [fullname] 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 | -------------------------------------------------------------------------------- /starter/gridsome.server.js: -------------------------------------------------------------------------------- 1 | // Server API makes it possible to hook into various parts of Gridsome 2 | // on server-side and add custom data to the GraphQL data layer. 3 | // Learn more: https://gridsome.org/docs/server-api/ 4 | 5 | // Changes here require a server restart. 6 | // To restart press CTRL + C in terminal and run `gridsome develop` 7 | 8 | module.exports = function (api) { 9 | api.loadSource((store) => { 10 | // Use the Data Store API here: https://gridsome.org/docs/data-store-api/ 11 | }) 12 | 13 | // Fetch all Strapi projects 14 | api.createPages(async ({ createPage, graphql }) => { 15 | // Use the Pages API here: https://gridsome.org/docs/pages-api/ 16 | const { data } = await graphql(`{ 17 | strapi { 18 | projects { 19 | slug 20 | } 21 | } 22 | }`) 23 | 24 | // Create a page for each project 25 | data.strapi.projects.forEach((project) => { 26 | createPage({ 27 | path: `/project/${project.slug}`, 28 | component: './src/templates/Project.vue', 29 | context: { 30 | slug: project.slug 31 | } 32 | }) 33 | }) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /starter/src/layouts/Default.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | query { 15 | strapi { 16 | global { 17 | siteName 18 | siteLanguage 19 | favicon { 20 | url 21 | } 22 | } 23 | } 24 | } 25 | 26 | 27 | 54 | -------------------------------------------------------------------------------- /starter/src/pages/About.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 26 | 27 | 28 | query { 29 | strapi { 30 | about { 31 | content { 32 | __typename 33 | ... on strapiTypes_ComponentSectionsRichText { 34 | id 35 | content 36 | } 37 | ... on strapiTypes_ComponentSectionsLargeMedia { 38 | id 39 | media { 40 | id 41 | url 42 | mime 43 | } 44 | description 45 | } 46 | ... on strapiTypes_ComponentSectionsImagesSlider { 47 | id 48 | title 49 | images { 50 | id 51 | url 52 | } 53 | } 54 | } 55 | seo { 56 | title 57 | description 58 | shareImage { 59 | id 60 | url 61 | } 62 | } 63 | } 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /starter/src/components/ProjectCard.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | -------------------------------------------------------------------------------- /starter/src/pages/Index.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | query { 27 | strapi { 28 | # Get homepage data 29 | home { 30 | title 31 | bio 32 | # Metadata for SEO 33 | seo { 34 | title 35 | description 36 | shareImage { 37 | id 38 | url 39 | } 40 | } 41 | } 42 | # List projects 43 | projects(sort: "date:desc") { 44 | title 45 | slug 46 | description 47 | categories { 48 | id 49 | title 50 | } 51 | coverImage { 52 | id 53 | url 54 | } 55 | } 56 | } 57 | } 58 | 59 | 60 | 84 | 85 | 91 | -------------------------------------------------------------------------------- /starter/src/templates/Project.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | query ($slug: String!) { 21 | strapi { 22 | projects(where: { slug: $slug }) { 23 | id 24 | title 25 | slug 26 | description 27 | categories { 28 | id 29 | title 30 | } 31 | coverImage { 32 | id 33 | url 34 | } 35 | content { 36 | __typename 37 | ... on strapiTypes_ComponentSectionsRichText { 38 | id 39 | content 40 | } 41 | ... on strapiTypes_ComponentSectionsLargeMedia { 42 | id 43 | media { 44 | id 45 | url 46 | mime 47 | } 48 | description 49 | } 50 | ... on strapiTypes_ComponentSectionsImagesSlider { 51 | id 52 | title 53 | images { 54 | id 55 | url 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | 63 | 64 | 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **:no_entry: DEPRECATED** 2 | 3 | This repository is no longer maintained and only works for Strapi v3. To find the newest Strapi v4 starters, check out the [starters-and-templates monorepo](https://github.com/strapi/starters-and-templates/). 4 | 5 | --- 6 | 7 | # Strapi Starter Gridsome Portfolio 8 | 9 | Gridsome starter for creating a corporate site with Strapi. 10 | 11 | [View the live demo](https://strapi-starter-gridsome-portfolio.vercel.app/) • [Watch the video tutorial](https://www.youtube.com/watch?v=4g3Pzj-wdXo&feature=youtu.be) • [Read the blog post](https://strapi.io/blog/strapi-starter-gridsome-portfolio) 12 | 13 | [![screen](/screenshot.png)](https://strapi-starter-gridsome-portfolio.vercel.app/) 14 | 15 | This starter allows you to easily create a website to showcase your work. It also makes it easy to keep it up to date thanks to Strapi. 16 | 17 | It relies on several Strapi features: 18 | 19 | * Collection types for projects and categories 20 | * Single types for the homepage, the about page and the global config 21 | * Components for reusable UI components and SEO metadata 22 | * Dynamic zones to have full control over your content 23 | 24 | On the frontend, we're using [Gridsome](https://gridsome.org/), a Vue.js framework for static sites. It uses GraphQL to query data and Tailwind CSS for styles. 25 | 26 | This starter uses the [Strapi portfolio template](https://github.com/strapi/strapi-template-portfolio) 27 | 28 | Check out all of our starters [here](https://strapi.io/starters) 29 | 30 | ## Getting started 31 | 32 | Use our `create-strapi-starter` CLI to create your project. 33 | 34 | ```sh 35 | npx create-strapi-starter@3 my-project gridsome-portfolio 36 | ``` 37 | 38 | The CLI will create a monorepo, install dependencies, and run your project automatically. 39 | 40 | The Gridsome frontend server will run here => [http://localhost:8080](http://localhost:8080) 41 | 42 | The Strapi backend server will run here => [http://localhost:1337](http://localhost:1337) 43 | 44 | ## Deploying to production 45 | 46 | You will need to deploy the `frontend` and `backend` projects separately. Here are the docs to deploy each one: 47 | 48 | - [Deploy Strapi](https://strapi.io/documentation/developer-docs/latest/setup-deployment-guides/deployment.html#hosting-provider-guides) 49 | - [Deploy Gridsome](https://gridsome.org/docs/deployment/) 50 | 51 | Don't forget to setup the environment variables on your production app: 52 | 53 | For the frontend the following environment variable is required: 54 | - `GRIDSOME_STRAPI_URL`: URL of your Strapi backend, without trailing slash 55 | 56 | Enjoy this starter! 57 | -------------------------------------------------------------------------------- /starter/src/components/Footer.vue: -------------------------------------------------------------------------------- 1 | 52 | 53 | 83 | 84 | 85 | query { 86 | strapi { 87 | global { 88 | siteName 89 | contactEmail 90 | socialNetworks { 91 | id 92 | url 93 | title 94 | icon { 95 | id 96 | url 97 | } 98 | } 99 | } 100 | projects { 101 | id 102 | slug 103 | } 104 | } 105 | } 106 | 107 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/macos,windows,visualstudiocode,node,linux 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=macos,windows,visualstudiocode,node,linux 4 | 5 | ### Linux ### 6 | *~ 7 | 8 | # temporary files which can be created if a process still has a handle open of a deleted file 9 | .fuse_hidden* 10 | 11 | # KDE directory preferences 12 | .directory 13 | 14 | # Linux trash folder which might appear on any partition or disk 15 | .Trash-* 16 | 17 | # .nfs files are created when an open file is removed but is still being accessed 18 | .nfs* 19 | 20 | ### macOS ### 21 | # General 22 | .DS_Store 23 | .AppleDouble 24 | .LSOverride 25 | 26 | # Icon must end with two \r 27 | Icon 28 | 29 | # Thumbnails 30 | ._* 31 | 32 | # Files that might appear in the root of a volume 33 | .DocumentRevisions-V100 34 | .fseventsd 35 | .Spotlight-V100 36 | .TemporaryItems 37 | .Trashes 38 | .VolumeIcon.icns 39 | .com.apple.timemachine.donotpresent 40 | 41 | # Directories potentially created on remote AFP share 42 | .AppleDB 43 | .AppleDesktop 44 | Network Trash Folder 45 | Temporary Items 46 | .apdisk 47 | 48 | ### Node ### 49 | # Logs 50 | logs 51 | *.log 52 | npm-debug.log* 53 | yarn-debug.log* 54 | yarn-error.log* 55 | lerna-debug.log* 56 | 57 | # Diagnostic reports (https://nodejs.org/api/report.html) 58 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 59 | 60 | # Runtime data 61 | pids 62 | *.pid 63 | *.seed 64 | *.pid.lock 65 | 66 | # Directory for instrumented libs generated by jscoverage/JSCover 67 | lib-cov 68 | 69 | # Coverage directory used by tools like istanbul 70 | coverage 71 | *.lcov 72 | 73 | # nyc test coverage 74 | .nyc_output 75 | 76 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 77 | .grunt 78 | 79 | # Bower dependency directory (https://bower.io/) 80 | bower_components 81 | 82 | # node-waf configuration 83 | .lock-wscript 84 | 85 | # Compiled binary addons (https://nodejs.org/api/addons.html) 86 | build/Release 87 | 88 | # Dependency directories 89 | node_modules/ 90 | jspm_packages/ 91 | 92 | # TypeScript v1 declaration files 93 | typings/ 94 | 95 | # TypeScript cache 96 | *.tsbuildinfo 97 | 98 | # Optional npm cache directory 99 | .npm 100 | 101 | # Optional eslint cache 102 | .eslintcache 103 | 104 | # Microbundle cache 105 | .rpt2_cache/ 106 | .rts2_cache_cjs/ 107 | .rts2_cache_es/ 108 | .rts2_cache_umd/ 109 | 110 | # Optional REPL history 111 | .node_repl_history 112 | 113 | # Output of 'npm pack' 114 | *.tgz 115 | 116 | # Yarn Integrity file 117 | .yarn-integrity 118 | 119 | # dotenv environment variables file 120 | .env 121 | .env.test 122 | 123 | # parcel-bundler cache (https://parceljs.org/) 124 | .cache 125 | 126 | # Next.js build output 127 | .next 128 | 129 | # Nuxt.js build / generate output 130 | .nuxt 131 | dist 132 | 133 | # Gatsby files 134 | .cache/ 135 | # Comment in the public line in if your project uses Gatsby and not Next.js 136 | # https://nextjs.org/blog/next-9-1#public-directory-support 137 | # public 138 | 139 | # vuepress build output 140 | .vuepress/dist 141 | 142 | # Serverless directories 143 | .serverless/ 144 | 145 | # FuseBox cache 146 | .fusebox/ 147 | 148 | # DynamoDB Local files 149 | .dynamodb/ 150 | 151 | # TernJS port file 152 | .tern-port 153 | 154 | # Stores VSCode versions used for testing VSCode extensions 155 | .vscode-test 156 | 157 | ### VisualStudioCode ### 158 | .vscode/* 159 | !.vscode/settings.json 160 | !.vscode/tasks.json 161 | !.vscode/launch.json 162 | !.vscode/extensions.json 163 | *.code-workspace 164 | 165 | ### VisualStudioCode Patch ### 166 | # Ignore all local history of files 167 | .history 168 | 169 | ### Windows ### 170 | # Windows thumbnail cache files 171 | Thumbs.db 172 | Thumbs.db:encryptable 173 | ehthumbs.db 174 | ehthumbs_vista.db 175 | 176 | # Dump file 177 | *.stackdump 178 | 179 | # Folder config file 180 | [Dd]esktop.ini 181 | 182 | # Recycle Bin used on file shares 183 | $RECYCLE.BIN/ 184 | 185 | # Windows Installer files 186 | *.cab 187 | *.msi 188 | *.msix 189 | *.msm 190 | *.msp 191 | 192 | # Windows shortcuts 193 | *.lnk 194 | 195 | # End of https://www.toptal.com/developers/gitignore/api/macos,windows,visualstudiocode,node,linux 196 | 197 | # Custom 198 | 199 | .vscode --------------------------------------------------------------------------------