Skip to content

Commit c390789

Browse files
committed
Initial commit
0 parents  commit c390789

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+4524
-0
lines changed

.eslintrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "next",
3+
"root": true,
4+
"rules": {
5+
"import/no-unresolved": 2
6+
}
7+
}

.gitignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
16

.prettierrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"tabWidth": 2,
3+
"useTabs": false,
4+
"singleQuote": true,
5+
"semi": false
6+
}

@types/remark-html.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare module 'remark-html'

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# A statically generated blog example using Next.js, Markdown, and TypeScript
2+
3+
This is the existing [blog-starter](https://github.com/vercel/next.js/tree/canary/examples/blog-starter) plus TypeScript.
4+
5+
This example showcases Next.js's [Static Generation](https://nextjs.org/docs/basic-features/pages) feature using Markdown files as the data source.
6+
7+
The blog posts are stored in `/_posts` as Markdown files with front matter support. Adding a new Markdown file in there will create a new blog post.
8+
9+
To create the blog posts we use [`remark`](https://github.com/remarkjs/remark) and [`remark-html`](https://github.com/remarkjs/remark-html) to convert the Markdown files into an HTML string, and then send it down as a prop to the page. The metadata of every post is handled by [`gray-matter`](https://github.com/jonschlinkert/gray-matter) and also sent in props to the page.
10+
11+
## Deploy your own
12+
13+
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/blog-starter-typescript)
14+
15+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/blog-starter-typescript&project-name=blog-starter-typescript&repository-name=blog-starter-typescript)
16+
17+
## How to use
18+
19+
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
20+
21+
```bash
22+
npx create-next-app --example blog-starter-typescript blog-starter-typescript-app
23+
# or
24+
yarn create next-app --example blog-starter-typescript blog-starter-typescript-app
25+
# or
26+
pnpm create next-app -- --example blog-starter-typescript blog-starter-typescript-app
27+
```
28+
29+
Your blog should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions).
30+
31+
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
32+
33+
# Notes
34+
35+
`blog-starter-typescript` uses [Tailwind CSS](https://tailwindcss.com) [(v3.0)](https://tailwindcss.com/blog/tailwindcss-v3).

_posts/dynamic-routing.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
title: 'Dynamic Routing and Static Generation'
3+
excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus.'
4+
coverImage: '/assets/blog/dynamic-routing/cover.jpg'
5+
date: '2020-03-16T05:35:07.322Z'
6+
author:
7+
name: JJ Kasper
8+
picture: '/assets/blog/authors/jj.jpeg'
9+
ogImage:
10+
url: '/assets/blog/dynamic-routing/cover.jpg'
11+
---
12+
13+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus. Praesent elementum facilisis leo vel fringilla. Congue mauris rhoncus aenean vel. Egestas sed tempus urna et pharetra pharetra massa massa ultricies.
14+
15+
Venenatis cras sed felis eget velit. Consectetur libero id faucibus nisl tincidunt. Gravida in fermentum et sollicitudin ac orci phasellus egestas tellus. Volutpat consequat mauris nunc congue nisi vitae. Id aliquet risus feugiat in ante metus dictum at tempor. Sed blandit libero volutpat sed cras. Sed odio morbi quis commodo odio aenean sed adipiscing. Velit euismod in pellentesque massa placerat. Mi bibendum neque egestas congue quisque egestas diam in arcu. Nisi lacus sed viverra tellus in. Nibh cras pulvinar mattis nunc sed. Luctus accumsan tortor posuere ac ut consequat semper viverra. Fringilla ut morbi tincidunt augue interdum velit euismod.
16+
17+
## Lorem Ipsum
18+
19+
Tristique senectus et netus et malesuada fames ac turpis. Ridiculous mus mauris vitae ultricies leo integer malesuada nunc vel. In mollis nunc sed id semper. Egestas tellus rutrum tellus pellentesque. Phasellus vestibulum lorem sed risus ultricies tristique nulla. Quis blandit turpis cursus in hac habitasse platea dictumst quisque. Eros donec ac odio tempor orci dapibus ultrices. Aliquam sem et tortor consequat id porta nibh. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo nulla. Diam vulputate ut pharetra sit amet. Ut tellus elementum sagittis vitae et leo. Arcu non odio euismod lacinia at quis risus sed vulputate.

_posts/hello-world.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
title: 'Learn How to Pre-render Pages Using Static Generation with Next.js'
3+
excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus.'
4+
coverImage: '/assets/blog/hello-world/cover.jpg'
5+
date: '2020-03-16T05:35:07.322Z'
6+
author:
7+
name: Tim Neutkens
8+
picture: '/assets/blog/authors/tim.jpeg'
9+
ogImage:
10+
url: '/assets/blog/hello-world/cover.jpg'
11+
---
12+
13+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus. Praesent elementum facilisis leo vel fringilla. Congue mauris rhoncus aenean vel. Egestas sed tempus urna et pharetra pharetra massa massa ultricies.
14+
15+
Venenatis cras sed felis eget velit. Consectetur libero id faucibus nisl tincidunt. Gravida in fermentum et sollicitudin ac orci phasellus egestas tellus. Volutpat consequat mauris nunc congue nisi vitae. Id aliquet risus feugiat in ante metus dictum at tempor. Sed blandit libero volutpat sed cras. Sed odio morbi quis commodo odio aenean sed adipiscing. Velit euismod in pellentesque massa placerat. Mi bibendum neque egestas congue quisque egestas diam in arcu. Nisi lacus sed viverra tellus in. Nibh cras pulvinar mattis nunc sed. Luctus accumsan tortor posuere ac ut consequat semper viverra. Fringilla ut morbi tincidunt augue interdum velit euismod.
16+
17+
## Lorem Ipsum
18+
19+
Tristique senectus et netus et malesuada fames ac turpis. Ridiculous mus mauris vitae ultricies leo integer malesuada nunc vel. In mollis nunc sed id semper. Egestas tellus rutrum tellus pellentesque. Phasellus vestibulum lorem sed risus ultricies tristique nulla. Quis blandit turpis cursus in hac habitasse platea dictumst quisque. Eros donec ac odio tempor orci dapibus ultrices. Aliquam sem et tortor consequat id porta nibh. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo nulla. Diam vulputate ut pharetra sit amet. Ut tellus elementum sagittis vitae et leo. Arcu non odio euismod lacinia at quis risus sed vulputate.

_posts/preview.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
title: 'Preview Mode for Static Generation'
3+
excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus.'
4+
coverImage: '/assets/blog/preview/cover.jpg'
5+
date: '2020-03-16T05:35:07.322Z'
6+
author:
7+
name: Joe Haddad
8+
picture: '/assets/blog/authors/joe.jpeg'
9+
ogImage:
10+
url: '/assets/blog/preview/cover.jpg'
11+
---
12+
13+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus. Praesent elementum facilisis leo vel fringilla. Congue mauris rhoncus aenean vel. Egestas sed tempus urna et pharetra pharetra massa massa ultricies.
14+
15+
Venenatis cras sed felis eget velit. Consectetur libero id faucibus nisl tincidunt. Gravida in fermentum et sollicitudin ac orci phasellus egestas tellus. Volutpat consequat mauris nunc congue nisi vitae. Id aliquet risus feugiat in ante metus dictum at tempor. Sed blandit libero volutpat sed cras. Sed odio morbi quis commodo odio aenean sed adipiscing. Velit euismod in pellentesque massa placerat. Mi bibendum neque egestas congue quisque egestas diam in arcu. Nisi lacus sed viverra tellus in. Nibh cras pulvinar mattis nunc sed. Luctus accumsan tortor posuere ac ut consequat semper viverra. Fringilla ut morbi tincidunt augue interdum velit euismod.
16+
17+
## Lorem Ipsum
18+
19+
Tristique senectus et netus et malesuada fames ac turpis. Ridiculous mus mauris vitae ultricies leo integer malesuada nunc vel. In mollis nunc sed id semper. Egestas tellus rutrum tellus pellentesque. Phasellus vestibulum lorem sed risus ultricies tristique nulla. Quis blandit turpis cursus in hac habitasse platea dictumst quisque. Eros donec ac odio tempor orci dapibus ultrices. Aliquam sem et tortor consequat id porta nibh. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo nulla. Diam vulputate ut pharetra sit amet. Ut tellus elementum sagittis vitae et leo. Arcu non odio euismod lacinia at quis risus sed vulputate.

next-env.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/image-types/global" />
3+
4+
// NOTE: This file should not be edited
5+
// see https://nextjs.org/docs/basic-features/typescript for more information.

package.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"dev": "next",
5+
"build": "next build",
6+
"start": "next start",
7+
"typecheck": "tsc"
8+
},
9+
"dependencies": {
10+
"@emotion/react": "^11.9.0",
11+
"@emotion/styled": "^11.8.1",
12+
"@mui/material": "^5.6.4",
13+
"classnames": "2.3.1",
14+
"date-fns": "2.21.3",
15+
"gray-matter": "4.0.3",
16+
"next": "latest",
17+
"react": "^17.0.2",
18+
"react-dom": "^17.0.2",
19+
"react-remark": "^2.1.0",
20+
"remark": "14.0.2",
21+
"remark-html": "15.0.1",
22+
"typescript": "^4.2.4"
23+
},
24+
"devDependencies": {
25+
"@types/jest": "^26.0.23",
26+
"@types/node": "^15.6.0",
27+
"@types/react": "^17.0.6",
28+
"@types/react-dom": "^17.0.5",
29+
"autoprefixer": "^10.4.7",
30+
"eslint": "^8.14.0",
31+
"eslint-config-next": "^12.1.6",
32+
"postcss": "^8.4.13",
33+
"tailwindcss": "^3.0.24"
34+
}
35+
}

postcss.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
}
308 KB
Loading
267 KB
Loading
4.68 KB
Loading
14.3 KB
Loading

public/favicon/apple-touch-icon.png

1.3 KB
Loading

public/favicon/browserconfig.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<browserconfig>
3+
<msapplication>
4+
<tile>
5+
<square150x150logo src="/favicons/mstile-150x150.png"/>
6+
<TileColor>#000000</TileColor>
7+
</tile>
8+
</msapplication>
9+
</browserconfig>

public/favicon/favicon-16x16.png

595 Bytes
Loading

public/favicon/favicon-32x32.png

880 Bytes
Loading

public/favicon/favicon.ico

14.7 KB
Binary file not shown.

public/favicon/mstile-150x150.png

3.48 KB
Loading

public/favicon/safari-pinned-tab.svg

Lines changed: 33 additions & 0 deletions
Loading

public/favicon/site.webmanifest

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "Next.js",
3+
"short_name": "Next.js",
4+
"icons": [
5+
{
6+
"src": "/favicons/android-chrome-192x192.png",
7+
"sizes": "192x192",
8+
"type": "image/png"
9+
},
10+
{
11+
"src": "/favicons/android-chrome-512x512.png",
12+
"sizes": "512x512",
13+
"type": "image/png"
14+
}
15+
],
16+
"theme_color": "#000000",
17+
"background_color": "#000000",
18+
"display": "standalone"
19+
}

script/api.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import fs from 'fs'
2+
import { join } from 'path'
3+
import matter from 'gray-matter'
4+
5+
const postsDirectory = join(process.cwd(), '_posts')
6+
7+
export function getPostSlugs() {
8+
return fs.readdirSync(postsDirectory)
9+
}
10+
11+
export function getPostBySlug(slug: string, fields: string[] = []) {
12+
const realSlug = slug.replace(/\.md$/, '')
13+
const fullPath = join(postsDirectory, `${realSlug}.md`)
14+
const fileContents = fs.readFileSync(fullPath, 'utf8')
15+
const { data, content } = matter(fileContents)
16+
17+
type Items = {
18+
[key: string]: string
19+
}
20+
21+
const items: Items = {}
22+
23+
// Ensure only the minimal needed data is exposed
24+
fields.forEach((field) => {
25+
if (field === 'slug') {
26+
items[field] = realSlug
27+
}
28+
if (field === 'content') {
29+
items[field] = content
30+
}
31+
32+
if (typeof data[field] !== 'undefined') {
33+
items[field] = data[field]
34+
}
35+
})
36+
37+
return items
38+
}
39+
40+
export function getAllPosts(fields: string[] = []) {
41+
const slugs = getPostSlugs()
42+
const posts = slugs
43+
.map((slug) => getPostBySlug(slug, fields))
44+
// sort posts by date in descending order
45+
.sort((post1, post2) => (post1.date > post2.date ? -1 : 1))
46+
return posts
47+
}

script/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export const EXAMPLE_PATH = 'blog-starter-typescript'
2+
export const CMS_NAME = 'Markdown'
3+
export const HOME_OG_IMAGE_URL =
4+
'https://og-image.vercel.app/Next.js%20Blog%20Starter%20Example.png?theme=light&md=1&fontSize=100px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg'

script/markdownToHtml.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { remark } from 'remark'
2+
import html from 'remark-html'
3+
4+
export default async function markdownToHtml(markdown: string) {
5+
const result = await remark().use(html).process(markdown)
6+
return result.toString()
7+
}

src/layout/Content/index.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React, { useState } from 'react'
2+
3+
type ContentProps = {}
4+
const Content: React.FC<ContentProps> = ({ children }) => {
5+
return (
6+
<section>
7+
{children}
8+
</section>
9+
)
10+
}
11+
12+
export default Content

src/layout/Header/Menu.tsx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React, { useState } from 'react'
2+
import Link from 'next/link'
3+
import { useRouter } from 'next/router'
4+
5+
type MenuProps = {}
6+
const Menu: React.FC<MenuProps> = () => {
7+
const router = useRouter()
8+
const menuItems = [
9+
{
10+
pathname: '/',
11+
label: 'Home',
12+
},
13+
{
14+
pathname: '/tags',
15+
label: 'Tags',
16+
},
17+
{
18+
pathname: '/about',
19+
label: 'About',
20+
},
21+
]
22+
return (
23+
<nav className="flex justify-center items-center">
24+
{menuItems.map((item) => {
25+
return (
26+
<span key={item.pathname}>
27+
{router.pathname === item.pathname ? (
28+
item.label
29+
) : (
30+
<Link
31+
href={{
32+
pathname: item.pathname,
33+
}}
34+
>
35+
{item.label}
36+
</Link>
37+
)}
38+
</span>
39+
)
40+
})}
41+
</nav>
42+
)
43+
}
44+
45+
export default Menu

src/layout/Header/index.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import React, { useState } from 'react'
2+
import Menu from '@/layout/Header/Menu'
3+
4+
type HeaderProps = {}
5+
const Header: React.FC<HeaderProps> = () => {
6+
return (
7+
<header>
8+
<Menu />
9+
</header>
10+
)
11+
}
12+
13+
export default Header

0 commit comments

Comments
 (0)