├── server-mock
├── jest.config.js
├── .gitignore
├── public
│ ├── favicon.ico
│ ├── icons
│ │ ├── logo.png
│ │ ├── logo2.png
│ │ ├── zap.svg
│ │ ├── user.svg
│ │ ├── book.svg
│ │ ├── bag.svg
│ │ ├── coffee.svg
│ │ ├── box.svg
│ │ ├── github.svg
│ │ └── shopping-bag.svg
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── mstile-150x150.png
│ ├── apple-touch-icon.png
│ ├── fonts
│ │ ├── Sahel-VF.woff2
│ │ ├── dana-bold.woff
│ │ ├── dana2webGX.woff
│ │ ├── DubaiW23-Bold.eot
│ │ ├── DubaiW23-Bold.ttf
│ │ ├── DubaiW23-Bold.woff
│ │ ├── DubaiW23-Light.eot
│ │ ├── DubaiW23-Light.ttf
│ │ ├── dana-regular.woff
│ │ ├── DubaiW23-Bold.woff2
│ │ ├── DubaiW23-Light.woff
│ │ ├── DubaiW23-Light.woff2
│ │ ├── DubaiW23-Medium.eot
│ │ ├── DubaiW23-Medium.ttf
│ │ ├── DubaiW23-Medium.woff
│ │ ├── DubaiW23-Regular.eot
│ │ ├── DubaiW23-Regular.ttf
│ │ ├── DubaiW23-Medium.woff2
│ │ ├── DubaiW23-Regular.woff
│ │ └── DubaiW23-Regular.woff2
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── img
│ │ ├── 51Y5NI-I5jL._AC_UX679_.jpg
│ │ ├── 51eg55uWmdL._AC_UX679_.jpg
│ │ ├── 61IBBVJvSDL._AC_SY879_.jpg
│ │ ├── 61U7T1koQqL._AC_SX679_.jpg
│ │ ├── 61mtL65D4cL._AC_SX679_.jpg
│ │ ├── 61pHAEJ4NML._AC_UX679_.jpg
│ │ ├── 71YXzeOuslL._AC_UY879_.jpg
│ │ ├── 71kWymZ+c+L._AC_SX679_.jpg
│ │ ├── 71li-ujtlUL._AC_UX679_.jpg
│ │ ├── 71z3kpMAYsL._AC_UY879_.jpg
│ │ ├── 81QpkIctqPL._AC_SX679_.jpg
│ │ ├── 81XH0e8fefL._AC_UY879_.jpg
│ │ ├── 81Zt42ioCgL._AC_SX679_.jpg
│ │ ├── 81fPKd-2AYL._AC_SL1500_.jpg
│ │ ├── 71HblAHs5xL._AC_UY879_-2.jpg
│ │ ├── 51UDEzMJVpL._AC_UL640_QL65_ML3_.jpg
│ │ ├── 61sbMiUnoGL._AC_UL640_QL65_ML3_.jpg
│ │ ├── 71YAIFU48IL._AC_UL640_QL65_ML3_.jpg
│ │ ├── 71pWzhdJNwL._AC_UL640_QL65_ML3_.jpg
│ │ └── 71-3HjGNDUL._AC_SY879._SX._UX._SY._UY_.jpg
│ ├── scss
│ │ ├── _badge.scss
│ │ ├── _table.scss
│ │ ├── master.scss
│ │ ├── _filters.scss
│ │ ├── _fonts.scss
│ │ ├── _variables.scss
│ │ ├── _modal.scss
│ │ ├── _typo.scss
│ │ ├── _code.scss
│ │ ├── _colors.scss
│ │ ├── _form.scss
│ │ ├── _reset.scss
│ │ ├── _grids.scss
│ │ ├── _nav.scss
│ │ ├── _buttons.scss
│ │ ├── _custom.scss
│ │ └── _general.scss
│ ├── browserconfig.xml
│ ├── site.webmanifest
│ ├── safari-pinned-tab.svg
│ ├── js
│ │ └── polyfill.min.js
│ └── dist
│ │ ├── master.min.css
│ │ └── master.min.css.map
├── controller
│ ├── home.js
│ ├── auth.js
│ ├── cart.js
│ ├── product.js
│ └── user.js
├── routes
│ ├── auth.js
│ ├── home.js
│ ├── user.js
│ ├── cart.js
│ └── product.js
├── README.md
├── docker-compose.yml
├── model
│ ├── product.js
│ ├── cart.js
│ └── user.js
├── package.json
├── dummyData.js
├── LICENSE
├── server.js
├── views
│ ├── shared
│ │ ├── footer.ejs
│ │ ├── authDocs.ejs
│ │ ├── aside.ejs
│ │ ├── header.ejs
│ │ ├── cartDocs.ejs
│ │ ├── productDocs.ejs
│ │ └── userDocs.ejs
│ └── home
│ │ ├── docs.ejs
│ │ └── index.ejs
└── __test__
│ ├── product.spec.js
│ ├── user.spec.js
│ └── cart.spec.js
├── nextjs-blog
├── public
│ ├── favicon.ico
│ └── vercel.svg
├── README.md
├── package.json
├── .gitignore
└── pages
│ ├── index.js
│ └── best
│ └── [category].js
└── README.md
/server-mock/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testEnvironment: 'node'
3 | };
--------------------------------------------------------------------------------
/server-mock/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | package-lock.json
4 | .vscode
5 | app.js
6 | Procfile
--------------------------------------------------------------------------------
/nextjs-blog/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/nextjs-blog/public/favicon.ico
--------------------------------------------------------------------------------
/server-mock/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/favicon.ico
--------------------------------------------------------------------------------
/nextjs-blog/README.md:
--------------------------------------------------------------------------------
1 | This is a starter template for [Learn Next.js](https://nextjs.org/learn).
2 |
3 |
4 | ### Start
5 | `npm run dev`
--------------------------------------------------------------------------------
/server-mock/public/icons/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/icons/logo.png
--------------------------------------------------------------------------------
/server-mock/public/icons/logo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/icons/logo2.png
--------------------------------------------------------------------------------
/server-mock/public/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/favicon-16x16.png
--------------------------------------------------------------------------------
/server-mock/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/favicon-32x32.png
--------------------------------------------------------------------------------
/server-mock/public/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/mstile-150x150.png
--------------------------------------------------------------------------------
/server-mock/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/server-mock/public/fonts/Sahel-VF.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/Sahel-VF.woff2
--------------------------------------------------------------------------------
/server-mock/public/fonts/dana-bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/dana-bold.woff
--------------------------------------------------------------------------------
/server-mock/public/fonts/dana2webGX.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/dana2webGX.woff
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Bold.eot
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Bold.ttf
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Bold.woff
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Light.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Light.eot
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Light.ttf
--------------------------------------------------------------------------------
/server-mock/public/fonts/dana-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/dana-regular.woff
--------------------------------------------------------------------------------
/server-mock/public/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/android-chrome-192x192.png
--------------------------------------------------------------------------------
/server-mock/public/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/android-chrome-512x512.png
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Bold.woff2
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Light.woff
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Light.woff2
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Medium.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Medium.eot
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Medium.ttf
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Medium.woff
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Regular.eot
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Regular.ttf
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Medium.woff2
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Regular.woff
--------------------------------------------------------------------------------
/server-mock/public/fonts/DubaiW23-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/fonts/DubaiW23-Regular.woff2
--------------------------------------------------------------------------------
/server-mock/public/img/51Y5NI-I5jL._AC_UX679_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/51Y5NI-I5jL._AC_UX679_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/51eg55uWmdL._AC_UX679_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/51eg55uWmdL._AC_UX679_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/61IBBVJvSDL._AC_SY879_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/61IBBVJvSDL._AC_SY879_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/61U7T1koQqL._AC_SX679_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/61U7T1koQqL._AC_SX679_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/61mtL65D4cL._AC_SX679_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/61mtL65D4cL._AC_SX679_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/61pHAEJ4NML._AC_UX679_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/61pHAEJ4NML._AC_UX679_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/71YXzeOuslL._AC_UY879_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/71YXzeOuslL._AC_UY879_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/71kWymZ+c+L._AC_SX679_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/71kWymZ+c+L._AC_SX679_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/71li-ujtlUL._AC_UX679_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/71li-ujtlUL._AC_UX679_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/71z3kpMAYsL._AC_UY879_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/71z3kpMAYsL._AC_UY879_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/81QpkIctqPL._AC_SX679_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/81QpkIctqPL._AC_SX679_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/81XH0e8fefL._AC_UY879_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/81XH0e8fefL._AC_UY879_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/81Zt42ioCgL._AC_SX679_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/81Zt42ioCgL._AC_SX679_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/81fPKd-2AYL._AC_SL1500_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/81fPKd-2AYL._AC_SL1500_.jpg
--------------------------------------------------------------------------------
/server-mock/public/scss/_badge.scss:
--------------------------------------------------------------------------------
1 | .badge {
2 | padding: 3px;
3 | border-radius: 2px;
4 | background-color: lighten($primary, 0.2);
5 | color: #fff;
6 | }
--------------------------------------------------------------------------------
/server-mock/public/img/71HblAHs5xL._AC_UY879_-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/71HblAHs5xL._AC_UY879_-2.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/51UDEzMJVpL._AC_UL640_QL65_ML3_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/51UDEzMJVpL._AC_UL640_QL65_ML3_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/61sbMiUnoGL._AC_UL640_QL65_ML3_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/61sbMiUnoGL._AC_UL640_QL65_ML3_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/71YAIFU48IL._AC_UL640_QL65_ML3_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/71YAIFU48IL._AC_UL640_QL65_ML3_.jpg
--------------------------------------------------------------------------------
/server-mock/public/img/71pWzhdJNwL._AC_UL640_QL65_ML3_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/71pWzhdJNwL._AC_UL640_QL65_ML3_.jpg
--------------------------------------------------------------------------------
/server-mock/controller/home.js:
--------------------------------------------------------------------------------
1 | module.exports.indexPage = (req,res) => {
2 | res.render('home/index')
3 | }
4 |
5 | module.exports.docsPage = (req,res) => {
6 | res.render('home/docs')
7 | }
--------------------------------------------------------------------------------
/server-mock/public/img/71-3HjGNDUL._AC_SY879._SX._UX._SY._UY_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agamm/next-programmatic-seo-tutorial/HEAD/server-mock/public/img/71-3HjGNDUL._AC_SY879._SX._UX._SY._UY_.jpg
--------------------------------------------------------------------------------
/server-mock/routes/auth.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const router = express.Router();
3 | const auth = require("../controller/auth");
4 |
5 | router.post("/login", auth.login);
6 |
7 | module.exports = router;
8 |
--------------------------------------------------------------------------------
/server-mock/routes/home.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const router = express.Router()
3 | const home = require('../controller/home')
4 |
5 | router.get('/',home.indexPage)
6 | router.get('/docs',home.docsPage)
7 |
8 | module.exports = router
--------------------------------------------------------------------------------
/server-mock/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Setup
4 | ```
5 | npm install .
6 | docker-compose up -d
7 | ```
8 |
9 | # Running
10 | `MONGO_MOCK_DB_CREDS='mongodb://admin:123456@127.0.0.1:27017' node server.js`
11 |
12 | # Populat with data (while server is running)
13 | `node dummyData.js`
--------------------------------------------------------------------------------
/server-mock/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.9'
2 |
3 | services:
4 | mongodb:
5 | image: mongo:5.0
6 | ports:
7 | - 27017:27017
8 | volumes:
9 | - ~/apps/mongo:/data/db
10 | environment:
11 | - MONGO_INITDB_ROOT_USERNAME=admin
12 | - MONGO_INITDB_ROOT_PASSWORD=123456
--------------------------------------------------------------------------------
/server-mock/public/icons/zap.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server-mock/public/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #802c6e
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/nextjs-blog/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "dev": "next dev",
5 | "build": "next build",
6 | "start": "next start"
7 | },
8 | "dependencies": {
9 | "next": "latest",
10 | "next-seo": "^5.2.0",
11 | "react": "17.0.2",
12 | "react-dom": "17.0.2"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/server-mock/public/scss/_table.scss:
--------------------------------------------------------------------------------
1 | table{
2 | width: 100%;
3 | border-collapse: collapse;
4 | }
5 | table tr td{
6 | border: 1px solid rgba(123,123,123,0.2);
7 | padding: 10px;
8 | }
9 | table a{
10 | margin: 10px;
11 | }
12 | table thead td{
13 | font-weight: 500;
14 | background-color: #f5f5f5;
15 | }
--------------------------------------------------------------------------------
/server-mock/public/icons/user.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server-mock/public/icons/book.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server-mock/public/scss/master.scss:
--------------------------------------------------------------------------------
1 | @import "fonts";
2 | @import "typo";
3 | @import "variables";
4 | @import "reset";
5 | @import "grids";
6 | @import "buttons";
7 | @import "general";
8 | @import "form";
9 | @import "colors";
10 | @import "filters";
11 | @import "modal";
12 | @import "table";
13 | @import "nav";
14 | @import "code";
15 | @import "custom";
16 | @import "badge";
--------------------------------------------------------------------------------
/server-mock/public/scss/_filters.scss:
--------------------------------------------------------------------------------
1 | @mixin grayscale($val){
2 | filter: grayscale($val);
3 | -webkit-filter: grayscale($val);
4 | }
5 | .grayscale-max{
6 | @include grayscale(100);
7 | }
8 | .grayscale-semi-max{
9 | @include grayscale(80);
10 | }
11 | .grayscale-mid{
12 | @include grayscale(50);
13 | }
14 | .grayscale-min{
15 | @include grayscale(30);
16 | }
--------------------------------------------------------------------------------
/server-mock/public/icons/bag.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server-mock/routes/user.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const router = express.Router()
3 | const user = require('../controller/user')
4 |
5 | router.get('/',user.getAllUser)
6 | router.get('/:id',user.getUser)
7 | router.post('/',user.addUser)
8 | router.put('/:id',user.editUser)
9 | router.patch('/:id',user.editUser)
10 | router.delete('/:id',user.deleteUser)
11 |
12 | module.exports = router
--------------------------------------------------------------------------------
/server-mock/public/icons/coffee.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server-mock/public/icons/box.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/nextjs-blog/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 |
21 | # debug
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
26 | # local env files
27 | .env.local
28 | .env.development.local
29 | .env.test.local
30 | .env.production.local
31 |
--------------------------------------------------------------------------------
/server-mock/public/scss/_fonts.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'dana VF';
3 | src: url('../fonts/dana2webGX.woff') format('woff-variations'),
4 | url('../fonts/dana2webGX.woff') format('woff');
5 | font-display: fallback;
6 | }
7 |
8 |
9 | @font-face {
10 | font-family: dana;
11 | src: url('../fonts/dana-regular.woff') format('woff');
12 | }
13 | @font-face {
14 | font-family: dana;
15 | src: url('../fonts/dana-bold.woff') format('woff');
16 | font-weight: 700;
17 | }
--------------------------------------------------------------------------------
/server-mock/routes/cart.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const router = express.Router()
3 | const cart = require('../controller/cart')
4 |
5 | router.get('/',cart.getAllCarts)
6 | router.get('/:id',cart.getSingleCart)
7 | router.get('/user/:userid',cart.getCartsbyUserid)
8 |
9 | router.post('/',cart.addCart)
10 | //router.post('/:id',cart.addtoCart)
11 |
12 | router.put('/:id',cart.editCart)
13 | router.patch('/:id',cart.editCart)
14 | router.delete('/:id',cart.deleteCart)
15 |
16 | module.exports = router
17 |
--------------------------------------------------------------------------------
/server-mock/public/icons/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server-mock/public/scss/_variables.scss:
--------------------------------------------------------------------------------
1 | $primary:#802c6e;
2 | $secondary:#f7aa35;
3 | $danger:#a71e22;
4 | $success:rgb(0, 233, 136);
5 | $warning:rgb(255, 211, 13);
6 | $muted:rgb(162, 162, 162);
7 | $light:#f5f5f5;
8 | $dark:rgb(121, 121, 121);
9 | $grey:rgb(143, 143, 148);
10 | $darkgrey:#494949;
11 | $black:rgb(27, 27, 27);
12 | $white:#fff;
13 | $mobile: 'only screen and (max-width:480px)';
14 | $tablet: 'only screen and (max-width:769px)';
15 | $small-desktop: 'only screen and (min-width:769px)';
16 | $desktop: 'only screen and (min-width:992px)';
--------------------------------------------------------------------------------
/server-mock/public/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Fake Store",
3 | "short_name": "Fake Store",
4 | "icons": [
5 | {
6 | "src": "/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/server-mock/routes/product.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const router = express.Router();
3 | const product = require("../controller/product");
4 |
5 | router.get("/", product.getAllProducts);
6 | router.get("/categories", product.getProductCategories);
7 | router.get("/category/:category", product.getProductsInCategory);
8 | router.get("/:id", product.getProduct);
9 | router.post("/", product.addProduct);
10 | router.put("/:id", product.editProduct);
11 | router.patch("/:id", product.editProduct);
12 | router.delete("/:id", product.deleteProduct);
13 |
14 | module.exports = router;
15 |
--------------------------------------------------------------------------------
/server-mock/model/product.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose')
2 | const schema = mongoose.Schema
3 |
4 | const productSchema = new schema({
5 | id:{
6 | type:Number,
7 | required:true
8 | },
9 | title:{
10 | type:String,
11 | required:true
12 | },
13 | price:{
14 | type:Number,
15 | required:true
16 | },
17 | rating:{
18 | type:Number,
19 | required:true
20 | },
21 | description:String,
22 | image:String,
23 | category:String
24 | })
25 |
26 | module.exports = mongoose.model('product',productSchema)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # next-programmatic-seo-tutorial
2 |
3 | > **Warning**
4 | > This is an old repo, use the new one:
5 |
6 |
7 | **New Next-13 Repository:**
8 | [agamm/pseo-next](https://github.com/agamm/pseo-next)
9 |
10 | ---
11 |
12 | A simplistic guide on how to use Next.js for a programmatic SEO project.
13 |
14 | Check more here: https://unzip.dev/0x003-programmatic-seo/
15 |
16 | Tutorial at: https://dev.to/agamm/programmatic-seo-with-nextjs-pmh
17 |
18 |
19 | ### Notes
20 |
21 | Make sure you are running:
22 | ```
23 | npm run build
24 | npm run start
25 | ```
26 | So Next.js will not re-generate the page each time (it does so in dev mode).
27 |
--------------------------------------------------------------------------------
/server-mock/controller/auth.js:
--------------------------------------------------------------------------------
1 | const User = require("../model/user");
2 |
3 | module.exports.login = (req, res) => {
4 | const username = req.body.username;
5 | const password = req.body.password;
6 |
7 | if (username && password) {
8 | User.findOne({
9 | username,
10 | })
11 | .then((user) => {
12 | if (!user) {
13 | res.json({
14 | status: "Error",
15 | msg: "username or password is incorrect",
16 | });
17 | } else {
18 | res.json({
19 | token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
20 | });
21 | }
22 | })
23 | .catch((err) => {
24 | console.log(err);
25 | });
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/server-mock/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api",
3 | "version": "1.0.0",
4 | "description": "FakeStoreAPI is a free online REST API that provides you fake e-commerce JSON data",
5 | "main": "server.js",
6 | "scripts": {
7 | "test": "jest",
8 | "start": "node server.js"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "axios": "^0.24.0",
14 | "bcryptjs": "^2.4.3",
15 | "cors": "^2.8.5",
16 | "express": "^4.17.1",
17 | "faker": "^5.5.3",
18 | "jsonwebtoken": "^8.5.1",
19 | "mongoose": "^5.9.6"
20 | },
21 | "devDependencies": {
22 | "ejs": "^3.1.6",
23 | "jest": "^27.0.6",
24 | "nodemon": "^2.0.9",
25 | "supertest": "^6.1.3"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/server-mock/public/scss/_modal.scss:
--------------------------------------------------------------------------------
1 | .modalwrapper{
2 | width: 100%;
3 | height: 100vh;
4 | position: fixed;
5 | top: 0;
6 | right: 0;
7 | left: 0;
8 | bottom: 0;
9 | z-index: 100;
10 | background-color: rgba(0,0,0,0.7);
11 | display: none;
12 | }
13 | .modal{
14 | width: 80%;
15 | height: 80vh;
16 | overflow: auto;
17 | position: absolute;
18 | top: 50%;
19 | left: 50%;
20 | transform: translate(-50%,-50%);
21 | border-radius: 3px;
22 | z-index: 99;
23 | background-color: #fff;
24 | padding: 30px;
25 | }
26 | .close{
27 | background-color: unset;
28 | border: unset;
29 | box-shadow: none;
30 | outline: none;
31 | float: right;
32 | font-size: 2.2em;
33 | cursor: pointer;
34 | }
35 | .hide{
36 | display: none;
37 | }
38 | .block{
39 | display: block;
40 | }
--------------------------------------------------------------------------------
/server-mock/model/cart.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose')
2 | const schema = mongoose.Schema
3 | const Product = require('./product')
4 | const User = require('./user')
5 |
6 | const cartSchema = new schema({
7 | id:{
8 | type:Number,
9 | required:true
10 | },
11 | userId:{
12 | type:schema.Types.Number,
13 | ref:User,
14 | required:true
15 | },
16 | date:{
17 | type:Date,
18 | required:true
19 | },
20 | products:[
21 | {
22 | productId:{
23 | type:schema.Types.Number,
24 | ref:Product,
25 | required:true
26 | },
27 | quantity:{
28 | type:Number,
29 | required:true
30 | }
31 | }
32 | ]
33 | })
34 |
35 | module.exports =mongoose.model('cart',cartSchema)
--------------------------------------------------------------------------------
/server-mock/dummyData.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 |
3 | const faker = require('Faker'); // let's hope this doesn't break again ;)
4 |
5 | const serverURL = 'http://127.0.0.1:6400';
6 |
7 | const amountOfData = 500;
8 | let requests = [];
9 |
10 |
11 | function between(min, max) {
12 | return Math.floor(
13 | Math.random() * (max - min) + min
14 | )
15 | }
16 |
17 |
18 | for (let i = 0; i < amountOfData; i++) {
19 | const data = {
20 | 'title': faker.commerce.productName(),
21 | 'price': faker.commerce.price(),
22 | 'description': faker.commerce.productDescription(),
23 | 'image': faker.image.cats(),
24 | 'category': faker.commerce.department(),
25 | 'rating': between(1,100)
26 | }
27 | const req = axios.post(`${serverURL}/products`, data);
28 |
29 | requests.push(req);
30 | }
31 |
32 | axios.all(requests).then(res => {
33 | console.log("Saved data.");
34 | }).catch(err => {
35 | console.log(err);
36 | });
--------------------------------------------------------------------------------
/server-mock/public/scss/_typo.scss:
--------------------------------------------------------------------------------
1 | body{
2 | font-size: 16px;
3 | }
4 | // *:not(.fab):not(.fas):not(.far):not(.fa){
5 | // font-family: Dubai;
6 | // }
7 |
8 | * {
9 | font-family: dana;
10 | }
11 | @supports (font-variation-settings: normal) {
12 | * {
13 | font-family: 'dana VF';
14 | font-variation-settings: "FANU" 0;
15 | }
16 | }
17 | h1,h2,h3{
18 | letter-spacing: -1px;
19 | }
20 | h1{
21 | font-variation-settings: "wght" 600;
22 | }
23 | h2{
24 | font-variation-settings: "wght" 500
25 | }
26 | h3{
27 | font-variation-settings: "wght" 400
28 | }
29 |
30 | h4,h5,h6{
31 | line-height: 2;
32 | margin: 15px 0;
33 | font-variation-settings: "wght" 300
34 | }
35 | p{
36 | line-height: 1.5;
37 | font-size: 1.1em;
38 | font-variation-settings: "wght" 200
39 | }
40 | a{
41 | // color: rgb(0, 0, 87);
42 | //font-size: 0.9em;
43 | color: rgb(0, 153, 255);
44 | }
45 | h1,h2,h3,h4,h5,h6,p,label{
46 | color: #3a3134;
47 | }
--------------------------------------------------------------------------------
/server-mock/model/user.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose')
2 | const schema = mongoose.Schema
3 |
4 | const userSchema = new schema({
5 | id:{
6 | type:Number,
7 | required:true
8 | },
9 | email:{
10 | type:String,
11 | required:true
12 | },
13 | username:{
14 | type:String,
15 | required:true
16 | },
17 | password:{
18 | type:String,
19 | required:true
20 | },
21 | name:{
22 | firstname:{
23 | type:String,
24 | required:true
25 | },
26 | lastname:{
27 | type:String,
28 | required:true
29 | }
30 | },
31 | address:{
32 | city:String,
33 | street:String,
34 | number:Number,
35 | zipcode:String,
36 | geolocation:{
37 | lat:String,
38 | long:String
39 | }
40 | },
41 | phone:String
42 | })
43 |
44 | module.exports = mongoose.model('user',userSchema)
--------------------------------------------------------------------------------
/server-mock/public/scss/_code.scss:
--------------------------------------------------------------------------------
1 | pre{
2 | width: 100%;
3 | border-radius: 7px;
4 | margin-bottom: 20px;
5 | }
6 | code{
7 | width: 100%;
8 | background-color: #f5f5f5;
9 | padding:20px;
10 | display: block;
11 | line-height: 1.5;
12 | font-size: 1.1em;
13 | font-weight: 300;
14 | letter-spacing: 2px;
15 | }
16 | code:empty{
17 | padding: 0;
18 | }
19 | #try{
20 | margin-top: 100px;
21 | code{
22 | overflow-x: auto;
23 | }
24 | }
25 | .c-comment{
26 | color: rgb(189, 189, 189);
27 | }
28 | .c-api{
29 | color: $primary;
30 |
31 | }
32 | .code-area{
33 | h2{
34 | font-size: 1.7em;
35 | }
36 | h3{
37 | margin-top: 50px;
38 | @media screen and (max-width:480px){
39 | margin-top: 30px;
40 | }
41 | font-size: 1.4em;
42 | }
43 | }
44 | pre{
45 | code{
46 | overflow-x: auto;
47 | }
48 | }
49 | .tips{
50 | color: $secondary;
51 | }
52 | .output-result{
53 | display: none;
54 | }
55 | .block{
56 | display: block;
57 | }
--------------------------------------------------------------------------------
/nextjs-blog/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server-mock/public/scss/_colors.scss:
--------------------------------------------------------------------------------
1 | /*background-color*/
2 | .primary{
3 | background-color: $primary;
4 | }
5 | .secondary{
6 | background-color: $secondary;
7 | }
8 | .danger{
9 | background-color: $danger;
10 | }
11 | .success{
12 | background-color: $success;
13 | }
14 | .warning{
15 | background-color: $warning;
16 | }
17 | .muted{
18 | background-color: $muted;
19 | }
20 | .light{
21 | background-color: $light;
22 | }
23 | .dark{
24 | background-color: $dark;
25 | }
26 | .black{
27 | background-color: $black;
28 | }
29 | .white{
30 | background-color: $white;
31 | }
32 | /*color*/
33 | .text-primary{
34 | color: $primary;
35 | }
36 | .text-secondary{
37 | color: $secondary;
38 | }
39 | .text-danger{
40 | color: $danger
41 | }
42 | .text-success{
43 | color: $success;
44 | }
45 | .text-warning{
46 | color: $warning;
47 | }
48 | .text-muted{
49 | color: $muted;
50 | }
51 | .text-light{
52 | color: $light;
53 | }
54 | .text-dark{
55 | color: $dark;
56 | }
57 | .text-black{
58 | color: $black;
59 | }
60 | .text-white{
61 | color: $white;
62 | }
--------------------------------------------------------------------------------
/server-mock/public/icons/shopping-bag.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server-mock/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 MohammadReza Keikavousi
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.
--------------------------------------------------------------------------------
/server-mock/server.js:
--------------------------------------------------------------------------------
1 | //initializes
2 | const mongoose = require("mongoose");
3 | const express = require("express");
4 | const cors = require("cors");
5 | const path = require("path");
6 |
7 | //app
8 | const app = express();
9 |
10 | //port
11 | const port = 6400;
12 | const mongoCreds = process.env.MONGO_MOCK_DB_CREDS; // process.env.MONGO_MOCK_DB_CREDS
13 |
14 | //routes
15 | const productRoute = require("./routes/product");
16 | const homeRoute = require("./routes/home");
17 | const cartRoute = require("./routes/cart");
18 | const userRoute = require("./routes/user");
19 | const authRoute = require("./routes/auth");
20 |
21 | //middleware
22 | app.use(cors());
23 |
24 | app.use(express.static(path.join(__dirname, "/public")));
25 | app.use(express.urlencoded({ extended: true }));
26 | app.use(express.json());
27 |
28 | //view engine
29 | app.set("view engine", "ejs");
30 | app.set("views", "views");
31 |
32 | app.disable("view cache");
33 |
34 | app.use("/", homeRoute);
35 | app.use("/products", productRoute);
36 | app.use("/carts", cartRoute);
37 | app.use("/users", userRoute);
38 | app.use("/auth", authRoute);
39 |
40 | //mongoose
41 | mongoose.set("useFindAndModify", false);
42 | mongoose.set("useUnifiedTopology", true);
43 | mongoose
44 | .connect(mongoCreds, { useNewUrlParser: true })
45 | .then(() => {
46 | app.listen(process.env.PORT || port, () => {
47 | console.log(`eCommerce API listening at ${process.env.PORT || port}...`);
48 | });
49 | })
50 | .catch((err) => {
51 | console.log(err);
52 | });
53 |
54 | module.exports = app;
55 |
--------------------------------------------------------------------------------
/server-mock/views/shared/footer.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
24 |
45 |
46 |