├── .eslintrc.json ├── .gitignore ├── README.md ├── components ├── Banner.js ├── Footer.js ├── Header.js ├── ItemPost.js ├── Post.js └── Sidebar.js ├── config.js ├── next-seo.config.js ├── next-sitemap.js ├── next.config.js ├── package-lock.json ├── package.json ├── pages ├── Search.js ├── _app.js ├── api │ └── hello.js ├── blog │ └── [slug].js ├── category │ └── [slug].js ├── index.js └── tag │ └── [slug].js ├── posts ├── how-is-npm-install-command.md ├── how-to-add-css-in-next-js.md ├── how-to-add-search-bar-functionality-in-ghost-cms-help-of-searchinghost.md ├── how-to-capture-screenshots-in-raspberry-pi-4.md ├── how-to-check-the-snap-store-package-available-for-raspberry-pi-4-or-not.md ├── html-version-history.md ├── keyboard-shortcut-keys-for-linux-terminal.md ├── npm-outdated-command.md ├── text-highlighting-in-html-5.md ├── title-tag-in-html-5.md └── what-is-next-js.md ├── public ├── banner.png ├── favicon.ico ├── images │ ├── HTML-Version-History.jpg │ ├── How-to-capture-screenshots-in-Raspberry-PI-4.png │ ├── Linux-Basic-Introduction--1-.png │ ├── Text-Highlighting-In-HTML-5.png │ ├── Title-tag-In-HTML-5.jpg │ ├── firstway-2.png │ ├── firstway.png │ ├── geenome.png │ ├── gnome-screenshots.png │ ├── next.js-add-css-code.jpg │ ├── next.js.png │ ├── npm-commands.png │ ├── npm-init-command-1.png │ ├── secondway.png │ └── the-snap-store.png ├── robots.txt ├── sitemap-0.xml ├── sitemap.xml └── vercel.svg ├── search.json ├── styles ├── Home.module.css └── globals.css └── utils └── index.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.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 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Build static website with markdown and nextjs. 2 | In nextjs we provide sitemap, SEO and Search support. 3 | 4 | ## Follow Article Series 5 | https://medium.com/nextjs/build-the-static-blog-with-next-js-and-markdown-59576c75fbf2 6 | 7 | https://medium.com/nextjs/build-the-static-blog-with-next-js-and-markdown-d438c2f74297 8 | 9 | https://medium.com/nextjs/build-the-search-functionality-in-a-static-blog-with-next-js-and-markdown-33ebc5a2214e 10 | 11 | https://medium.com/nextjs/build-the-seo-and-sitemap-functionality-in-a-static-blog-with-next-js-and-markdown-d0b62c83d7f2 12 | 13 | 14 | 15 | ## step 16 | 1. Download code 17 | 2. Run the `npm install` 18 | 3. To start local develpoment server run ` npm run dev` 19 | 20 | ## Note 21 | change your ` localhost:3000 ` url in `./config.js` url. 22 | 23 | ## HTML Template 24 | https://startbootstrap.com/template/blog-home 25 | -------------------------------------------------------------------------------- /components/Banner.js: -------------------------------------------------------------------------------- 1 | export default function Banner() { 2 | return( 3 |
4 |
5 |
6 |

Welcome to my blog home page

7 |

Build nextjs blog website with Markdown, sitemap, serachbar, category, tag and SEO support

8 |
9 |
10 |
11 | ) 12 | } -------------------------------------------------------------------------------- /components/Footer.js: -------------------------------------------------------------------------------- 1 | export default function Footer() { 2 | return 5 | } -------------------------------------------------------------------------------- /components/Header.js: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | export default function Header() { 3 | return (<> 4 | 5 | 30 | 31 | ) 32 | } -------------------------------------------------------------------------------- /components/ItemPost.js: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | 3 | import { ImageUrl } from "../utils"; 4 | 5 | export default function ItemPost({ post: {post } }) { 6 | 7 | // const imageUrl= process.env.SITE_URL + post.images[0] 8 | 9 | 10 | // console.log(imageUrl,' imageUrl ') 11 | 12 | const date = new Date(post.date) 13 | 14 | return ( 15 |
16 | {post.title} 17 |
18 |
{`${date.getMonth() + 1} - ${date.getDate()} - ${date.getFullYear()}`}
19 |

{post.title}

20 |

{post.summary}

21 | 22 | Read More 23 | 24 |
25 |
26 | 27 | 28 | ) 29 | } -------------------------------------------------------------------------------- /components/Post.js: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | import { slugify } from '../utils' 3 | 4 | export default function Post({ post }) { 5 | 6 | const date = new Date(post.frontmatter?.date) 7 | return ( 8 |
9 | ... 10 |
11 |
{`${date.getMonth() + 1} - ${date.getDate()} - ${date.getFullYear()}`}
12 | 13 |
{ 14 | post.frontmatter.tags.map( 15 | tag => { 16 | 17 | const slug = slugify(tag) 18 | 19 | return ( 20 | 21 |
#{tag}
22 |
23 | ) 24 | } 25 | ) 26 | }
27 |

{post.frontmatter.title}

28 |

{post.frontmatter.summary}

29 | 30 | Read More 31 | 32 |
33 |
34 | ) 35 | } -------------------------------------------------------------------------------- /components/Sidebar.js: -------------------------------------------------------------------------------- 1 | import { useState} from "react"; 2 | import Link from 'next/link' 3 | import Search from "../search.json"; 4 | import { slugify } from "../utils"; 5 | 6 | export default function Sidebar() { 7 | const [search, setSearch]= useState() 8 | function findSerach(value) { 9 | 10 | setSearch(value.target.value) 11 | } 12 | 13 | return ( 14 |
15 | 16 |
17 |
Search
18 |
19 |
20 | 21 | 22 | Go! 23 | 24 |
25 |
26 |
27 | 28 |
29 |
Categories
30 |
31 |
32 |
33 |
    34 | 35 | { 36 | Search?.map( 37 | post => { 38 | return post.frontmatter.categories.map( 39 | item => { 40 | const slug = slugify(item) 41 | 42 | return 43 |
  • {item}
  • 44 | 45 | } 46 | ) 47 | 48 | } 49 | ) 50 | } 51 |
52 |
53 | 54 |
55 |
56 |
57 | 58 |
59 |
Side Widget
60 |
You can put anything you want inside of these side widgets. They are easy to use, and feature the Bootstrap 5 card component!
61 |
62 |
63 | ) 64 | } -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | const SITE_URL= 'https://markdowbnextjsblog.vercel.app/' 2 | 3 | export default SITE_URL -------------------------------------------------------------------------------- /next-seo.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | openGraph: { 3 | type: 'website', 4 | locale: 'en_IE', 5 | url: 'https://markdownnextjs.com', 6 | site_name: 'Rajdeep Singh', 7 | }, 8 | twitter: { 9 | handle: '@Official_R_deep', 10 | site: '@Official_R_deep', 11 | cardType: 'summary_large_image', 12 | } 13 | }; -------------------------------------------------------------------------------- /next-sitemap.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next-sitemap').IConfig} */ 2 | 3 | module.exports = { 4 | siteUrl: process.env.SITE_URL || 'https://example.com', 5 | generateRobotsTxt: true, // (optional) 6 | // Default transformation function 7 | } -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | reactStrictMode: true, 3 | } 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "markdownblog", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "next": "12.1.5", 13 | "react": "18.1.0", 14 | "react-dom": "18.1.0" 15 | }, 16 | "devDependencies": { 17 | "eslint": "7.32.0", 18 | "eslint-config-next": "12.1.5", 19 | "gray-matter": "^4.0.3", 20 | "marked": "^4.0.14", 21 | "next-seo": "^5.4.0", 22 | "next-sitemap": "^2.5.20" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /pages/Search.js: -------------------------------------------------------------------------------- 1 | import Head from 'next/head' 2 | import Post from '../components/Post' 3 | import Banner from "../components/Banner"; 4 | import search from "../search.json"; 5 | import { useRouter } from 'next/router' 6 | import { NextSeo } from 'next-seo'; 7 | import { ImageUrl} from '../utils' 8 | 9 | export default function Search() { 10 | const { query } = useRouter() 11 | const TempPosts = [] 12 | 13 | search.map( 14 | (post) => { 15 | if (post.frontmatter.draft === false) { 16 | if (post.frontmatter.title.toLowerCase().includes(query.q) || post.frontmatter.summary.toLowerCase().includes(query.q) || post.frontmatter.description.toLowerCase().includes(query.q)) { 17 | TempPosts.push(post) 18 | } else { 19 | TempPosts.push(null) 20 | } 21 | } 22 | } 23 | ) 24 | 25 | // remove null in posts 26 | const posts = TempPosts.filter( 27 | path => { 28 | return path && path 29 | } 30 | ) 31 | 32 | return ( 33 |
34 | 53 | 54 |
55 |
56 | 57 |
58 | 59 | { 60 | posts.length > 0 ? 61 | posts.map((post, index) => ( 62 | 63 | )) :
64 |

65 | { query.q? `No post find base on ${query.q} `: 'loadding.. '} 66 |

67 |
68 | } 69 | 70 |
71 |
72 |
73 |
74 | ) 75 | } 76 | -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css' 2 | import Head from "next/head"; 3 | import Header from "../components/Header"; 4 | import Footer from "../components/Footer"; 5 | import { DefaultSeo } from 'next-seo'; 6 | import SEO from '../next-seo.config'; 7 | 8 | 9 | function MyApp({ Component, pageProps }) { 10 | return ( <> 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 |