Moves prettier and lint to root of the project (#143)

This commit is contained in:
Michael Novotny
2023-09-06 12:57:56 -05:00
committed by GitHub
parent a657dd215b
commit 1725e58866
135 changed files with 6730 additions and 765 deletions

5
basics/.gitignore vendored
View File

@@ -1,5 +0,0 @@
.next
node_modules
*.log
yarn.lock
package-lock.json

View File

@@ -1 +0,0 @@
18

View File

@@ -1,2 +0,0 @@
.next
node_modules

View File

@@ -1,7 +0,0 @@
{
"singleQuote": true,
"semi": false,
"trailingComma": "none",
"arrowParens": "avoid",
"endOfLine": "auto"
}

View File

@@ -1 +1 @@
This is a starter template for [Learn Next.js](https://nextjs.org/learn).
This is a starter template for [Learn Next.js](https://nextjs.org/learn).

View File

@@ -1,6 +1,6 @@
import { parseISO, format } from 'date-fns'
import { parseISO, format } from 'date-fns';
export default function Date({ dateString }) {
const date = parseISO(dateString)
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>
const date = parseISO(dateString);
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>;
}

View File

@@ -1,11 +1,11 @@
import Head from 'next/head'
import Image from 'next/image'
import styles from './layout.module.css'
import utilStyles from '../styles/utils.module.css'
import Link from 'next/link'
import Head from 'next/head';
import Image from 'next/image';
import styles from './layout.module.css';
import utilStyles from '../styles/utils.module.css';
import Link from 'next/link';
const name = '[Your Name]'
export const siteTitle = 'Next.js Sample Website'
const name = '[Your Name]';
export const siteTitle = 'Next.js Sample Website';
export default function Layout({ children, home }) {
return (
@@ -19,7 +19,7 @@ export default function Layout({ children, home }) {
<meta
property="og:image"
content={`https://og-image.vercel.app/${encodeURI(
siteTitle
siteTitle,
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.zeit.co%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
/>
<meta name="og:title" content={siteTitle} />
@@ -65,5 +65,5 @@ export default function Layout({ children, home }) {
</div>
)}
</div>
)
);
}

View File

@@ -1,69 +1,69 @@
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { remark } from 'remark'
import html from 'remark-html'
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { remark } from 'remark';
import html from 'remark-html';
const postsDirectory = path.join(process.cwd(), 'posts')
const postsDirectory = path.join(process.cwd(), 'posts');
export function getSortedPostsData() {
// Get file names under /posts
const fileNames = fs.readdirSync(postsDirectory)
const allPostsData = fileNames.map(fileName => {
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames.map((fileName) => {
// Remove ".md" from file name to get id
const id = fileName.replace(/\.md$/, '')
const id = fileName.replace(/\.md$/, '');
// Read markdown file as string
const fullPath = path.join(postsDirectory, fileName)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const matterResult = matter(fileContents);
// Combine the data with the id
return {
id,
...matterResult.data
}
})
...matterResult.data,
};
});
// Sort posts by date
return allPostsData.sort((a, b) => {
if (a.date < b.date) {
return 1
return 1;
} else {
return -1
return -1;
}
})
});
}
export function getAllPostIds() {
const fileNames = fs.readdirSync(postsDirectory)
return fileNames.map(fileName => {
const fileNames = fs.readdirSync(postsDirectory);
return fileNames.map((fileName) => {
return {
params: {
id: fileName.replace(/\.md$/, '')
}
}
})
id: fileName.replace(/\.md$/, ''),
},
};
});
}
export async function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const matterResult = matter(fileContents);
// Use remark to convert markdown into HTML string
const processedContent = await remark()
.use(html)
.process(matterResult.content)
const contentHtml = processedContent.toString()
.process(matterResult.content);
const contentHtml = processedContent.toString();
// Combine the data with the id and contentHtml
return {
id,
contentHtml,
...matterResult.data
}
...matterResult.data,
};
}

View File

@@ -1,11 +1,8 @@
{
"private": true,
"engines": {
"node": ">=18"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"dev": "next dev",
"start": "next start"
},
"dependencies": {
@@ -16,5 +13,8 @@
"react-dom": "18.2.0",
"remark": "^14.0.2",
"remark-html": "^15.0.1"
},
"engines": {
"node": ">=18"
}
}

View File

@@ -1,5 +1,5 @@
import '../styles/global.css'
import '../styles/global.css';
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
return <Component {...pageProps} />;
}

View File

@@ -1,9 +1,9 @@
import Head from 'next/head'
import Layout, { siteTitle } from '../components/layout'
import utilStyles from '../styles/utils.module.css'
import { getSortedPostsData } from '../lib/posts'
import Link from 'next/link'
import Date from '../components/date'
import Head from 'next/head';
import Layout, { siteTitle } from '../components/layout';
import utilStyles from '../styles/utils.module.css';
import { getSortedPostsData } from '../lib/posts';
import Link from 'next/link';
import Date from '../components/date';
export default function Home({ allPostsData }) {
return (
@@ -33,14 +33,14 @@ export default function Home({ allPostsData }) {
</ul>
</section>
</Layout>
)
);
}
export async function getStaticProps() {
const allPostsData = getSortedPostsData()
const allPostsData = getSortedPostsData();
return {
props: {
allPostsData
}
}
allPostsData,
},
};
}

View File

@@ -1,8 +1,8 @@
import Layout from '../../components/layout'
import { getAllPostIds, getPostData } from '../../lib/posts'
import Head from 'next/head'
import Date from '../../components/date'
import utilStyles from '../../styles/utils.module.css'
import Layout from '../../components/layout';
import { getAllPostIds, getPostData } from '../../lib/posts';
import Head from 'next/head';
import Date from '../../components/date';
import utilStyles from '../../styles/utils.module.css';
export default function Post({ postData }) {
return (
@@ -18,22 +18,22 @@ export default function Post({ postData }) {
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
</article>
</Layout>
)
);
}
export async function getStaticPaths() {
const paths = getAllPostIds()
const paths = getAllPostIds();
return {
paths,
fallback: false
}
fallback: false,
};
}
export async function getStaticProps({ params }) {
const postData = await getPostData(params.id)
const postData = await getPostData(params.id);
return {
props: {
postData
}
}
postData,
},
};
}

View File

@@ -2,8 +2,18 @@ html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family:
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
line-height: 1.6;
font-size: 18px;
}

View File

@@ -1 +1 @@
This is a starter template for [Learn Next.js](https://nextjs.org/learn).
This is a starter template for [Learn Next.js](https://nextjs.org/learn).

View File

@@ -1,16 +1,16 @@
{
"private": true,
"engines": {
"node": ">=18"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"dev": "next dev",
"start": "next start"
},
"dependencies": {
"next": "latest",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"engines": {
"node": ">=18"
}
}

View File

@@ -1,5 +1,5 @@
import Link from 'next/link';
import Head from 'next/head'
import Head from 'next/head';
import styles from '../styles/Home.module.css';
export default function Home() {
@@ -12,7 +12,7 @@ export default function Home() {
<main>
<h1 className={styles.title}>
Read <Link href='/posts/first-post'>this page!</Link>
Read <Link href="/posts/first-post">this page!</Link>
</h1>
<p className={styles.description}>
@@ -93,8 +93,15 @@ export default function Home() {
border-radius: 5px;
padding: 0.75rem;
font-size: 1.1rem;
font-family: Menlo, Monaco, Lucida Console, Liberation Mono,
DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
font-family:
Menlo,
Monaco,
Lucida Console,
Liberation Mono,
DejaVu Sans Mono,
Bitstream Vera Sans Mono,
Courier New,
monospace;
}
`}</style>
@@ -103,8 +110,17 @@ export default function Home() {
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue,
font-family:
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
}
* {
@@ -112,5 +128,5 @@ export default function Home() {
}
`}</style>
</div>
)
}
);
}

View File

@@ -1,4 +1,4 @@
import Link from 'next/link'
import Link from 'next/link';
export default function FirstPost() {
return (
@@ -8,5 +8,5 @@ export default function FirstPost() {
<Link href="/">Back to home</Link>
</h2>
</>
)
);
}

View File

@@ -33,7 +33,6 @@
text-align: center;
}
.description {
line-height: 1.5;
font-size: 1.5rem;
@@ -58,7 +57,9 @@
text-decoration: none;
border: 1px solid #eaeaea;
border-radius: 10px;
transition: color 0.15s ease, border-color 0.15s ease;
transition:
color 0.15s ease,
border-color 0.15s ease;
}
.card:hover,

View File

@@ -2,8 +2,19 @@ html,
body {
padding: 0;
margin: 0;
font-family: Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
}
a {

View File

@@ -1 +1 @@
This is a starter template for [Learn Next.js](https://nextjs.org/learn).
This is a starter template for [Learn Next.js](https://nextjs.org/learn).

View File

@@ -1,6 +1,6 @@
import { parseISO, format } from 'date-fns'
import { parseISO, format } from 'date-fns';
export default function Date({ dateString }) {
const date = parseISO(dateString)
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>
const date = parseISO(dateString);
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>;
}

View File

@@ -1,13 +1,13 @@
import Head from 'next/head'
import Image from 'next/image'
import Script from 'next/script'
import Head from 'next/head';
import Image from 'next/image';
import Script from 'next/script';
import styles from './layout.module.css'
import utilStyles from '../styles/utils.module.css'
import Link from 'next/link'
import styles from './layout.module.css';
import utilStyles from '../styles/utils.module.css';
import Link from 'next/link';
const name = '[Your Name]'
export const siteTitle = 'Next.js Sample Website'
const name = '[Your Name]';
export const siteTitle = 'Next.js Sample Website';
export default function Layout({ children, home }) {
return (
@@ -21,7 +21,7 @@ export default function Layout({ children, home }) {
<meta
property="og:image"
content={`https://og-image.vercel.app/${encodeURI(
siteTitle
siteTitle,
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.zeit.co%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
/>
<meta name="og:title" content={siteTitle} />
@@ -74,5 +74,5 @@ export default function Layout({ children, home }) {
</div>
)}
</div>
)
);
}

View File

@@ -1,69 +1,69 @@
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { remark } from 'remark'
import html from 'remark-html'
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { remark } from 'remark';
import html from 'remark-html';
const postsDirectory = path.join(process.cwd(), 'posts')
const postsDirectory = path.join(process.cwd(), 'posts');
export function getSortedPostsData() {
// Get file names under /posts
const fileNames = fs.readdirSync(postsDirectory)
const allPostsData = fileNames.map(fileName => {
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames.map((fileName) => {
// Remove ".md" from file name to get id
const id = fileName.replace(/\.md$/, '')
const id = fileName.replace(/\.md$/, '');
// Read markdown file as string
const fullPath = path.join(postsDirectory, fileName)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const matterResult = matter(fileContents);
// Combine the data with the id
return {
id,
...matterResult.data
}
})
...matterResult.data,
};
});
// Sort posts by date
return allPostsData.sort((a, b) => {
if (a.date < b.date) {
return 1
return 1;
} else {
return -1
return -1;
}
})
});
}
export function getAllPostIds() {
const fileNames = fs.readdirSync(postsDirectory)
return fileNames.map(fileName => {
const fileNames = fs.readdirSync(postsDirectory);
return fileNames.map((fileName) => {
return {
params: {
id: fileName.replace(/\.md$/, '')
}
}
})
id: fileName.replace(/\.md$/, ''),
},
};
});
}
export async function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const matterResult = matter(fileContents);
// Use remark to convert markdown into HTML string
const processedContent = await remark()
.use(html)
.process(matterResult.content)
const contentHtml = processedContent.toString()
.process(matterResult.content);
const contentHtml = processedContent.toString();
// Combine the data with the id and contentHtml
return {
id,
contentHtml,
...matterResult.data
}
...matterResult.data,
};
}

View File

@@ -1,11 +1,8 @@
{
"private": true,
"engines": {
"node": ">=18"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"dev": "next dev",
"start": "next start"
},
"dependencies": {
@@ -16,5 +13,8 @@
"react-dom": "18.2.0",
"remark": "^14.0.2",
"remark-html": "^15.0.1"
},
"engines": {
"node": ">=18"
}
}

View File

@@ -1,5 +1,5 @@
import '../styles/global.css'
import '../styles/global.css';
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
return <Component {...pageProps} />;
}

View File

@@ -1,3 +1,3 @@
export default (req, res) => {
res.status(200).json({ text: 'Hello' })
}
res.status(200).json({ text: 'Hello' });
};

View File

@@ -1,9 +1,9 @@
import Head from 'next/head'
import Layout, { siteTitle } from '../components/layout'
import utilStyles from '../styles/utils.module.css'
import { getSortedPostsData } from '../lib/posts'
import Link from 'next/link'
import Date from '../components/date'
import Head from 'next/head';
import Layout, { siteTitle } from '../components/layout';
import utilStyles from '../styles/utils.module.css';
import { getSortedPostsData } from '../lib/posts';
import Link from 'next/link';
import Date from '../components/date';
export default function Home({ allPostsData }) {
return (
@@ -33,14 +33,14 @@ export default function Home({ allPostsData }) {
</ul>
</section>
</Layout>
)
);
}
export async function getStaticProps() {
const allPostsData = getSortedPostsData()
const allPostsData = getSortedPostsData();
return {
props: {
allPostsData
}
}
allPostsData,
},
};
}

View File

@@ -1,8 +1,8 @@
import Layout from '../../components/layout'
import { getAllPostIds, getPostData } from '../../lib/posts'
import Head from 'next/head'
import Date from '../../components/date'
import utilStyles from '../../styles/utils.module.css'
import Layout from '../../components/layout';
import { getAllPostIds, getPostData } from '../../lib/posts';
import Head from 'next/head';
import Date from '../../components/date';
import utilStyles from '../../styles/utils.module.css';
export default function Post({ postData }) {
return (
@@ -18,22 +18,22 @@ export default function Post({ postData }) {
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
</article>
</Layout>
)
);
}
export async function getStaticPaths() {
const paths = getAllPostIds()
const paths = getAllPostIds();
return {
paths,
fallback: false
}
fallback: false,
};
}
export async function getStaticProps({ params }) {
const postData = await getPostData(params.id)
const postData = await getPostData(params.id);
return {
props: {
postData
}
}
postData,
},
};
}

View File

@@ -2,8 +2,18 @@ html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family:
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
line-height: 1.6;
font-size: 18px;
}

View File

@@ -1 +1 @@
This is a starter template for [Learn Next.js](https://nextjs.org/learn).
This is a starter template for [Learn Next.js](https://nextjs.org/learn).

View File

@@ -1,11 +1,11 @@
import Head from 'next/head'
import Image from 'next/image'
import styles from './layout.module.css'
import utilStyles from '../styles/utils.module.css'
import Link from 'next/link'
import Head from 'next/head';
import Image from 'next/image';
import styles from './layout.module.css';
import utilStyles from '../styles/utils.module.css';
import Link from 'next/link';
const name = '[Your Name]'
export const siteTitle = 'Next.js Sample Website'
const name = '[Your Name]';
export const siteTitle = 'Next.js Sample Website';
export default function Layout({ children, home }) {
return (
@@ -19,7 +19,7 @@ export default function Layout({ children, home }) {
<meta
property="og:image"
content={`https://og-image.vercel.app/${encodeURI(
siteTitle
siteTitle,
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.zeit.co%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
/>
<meta name="og:title" content={siteTitle} />
@@ -65,5 +65,5 @@ export default function Layout({ children, home }) {
</div>
)}
</div>
)
);
}

View File

@@ -1,16 +1,16 @@
{
"private": true,
"engines": {
"node": ">=18"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"dev": "next dev",
"start": "next start"
},
"dependencies": {
"next": "latest",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"engines": {
"node": ">=18"
}
}

View File

@@ -1,5 +1,5 @@
import '../styles/global.css'
import '../styles/global.css';
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
return <Component {...pageProps} />;
}

View File

@@ -1,6 +1,6 @@
import Head from 'next/head'
import Layout, { siteTitle } from '../components/layout'
import utilStyles from '../styles/utils.module.css'
import Head from 'next/head';
import Layout, { siteTitle } from '../components/layout';
import utilStyles from '../styles/utils.module.css';
export default function Home() {
return (
@@ -16,5 +16,5 @@ export default function Home() {
</p>
</section>
</Layout>
)
);
}

View File

@@ -1,6 +1,6 @@
import Head from 'next/head'
import Link from 'next/link'
import Layout from '../../components/layout'
import Head from 'next/head';
import Link from 'next/link';
import Layout from '../../components/layout';
export default function FirstPost() {
return (
@@ -13,5 +13,5 @@ export default function FirstPost() {
<Link href="/">Back to home</Link>
</h2>
</Layout>
)
);
}

View File

@@ -2,8 +2,18 @@ html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family:
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
line-height: 1.6;
font-size: 18px;
}

View File

@@ -1 +1 @@
This is a final template for [Learn Next.js](https://nextjs.org/learn).
This is a final template for [Learn Next.js](https://nextjs.org/learn).

View File

@@ -1,6 +1,6 @@
import { parseISO, format } from 'date-fns'
import { parseISO, format } from 'date-fns';
export default function Date({ dateString }) {
const date = parseISO(dateString)
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>
const date = parseISO(dateString);
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>;
}

View File

@@ -1,11 +1,11 @@
import Head from 'next/head'
import Image from 'next/image'
import styles from './layout.module.css'
import utilStyles from '../styles/utils.module.css'
import Link from 'next/link'
import Head from 'next/head';
import Image from 'next/image';
import styles from './layout.module.css';
import utilStyles from '../styles/utils.module.css';
import Link from 'next/link';
const name = 'Shu Uesugi'
export const siteTitle = 'Next.js Sample Website'
const name = 'Shu Uesugi';
export const siteTitle = 'Next.js Sample Website';
export default function Layout({ children, home }) {
return (
@@ -19,7 +19,7 @@ export default function Layout({ children, home }) {
<meta
property="og:image"
content={`https://og-image.vercel.app/${encodeURI(
siteTitle
siteTitle,
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.zeit.co%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
/>
<meta name="og:title" content={siteTitle} />
@@ -65,5 +65,5 @@ export default function Layout({ children, home }) {
</div>
)}
</div>
)
);
}

View File

@@ -1,69 +1,69 @@
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { remark } from 'remark'
import html from 'remark-html'
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { remark } from 'remark';
import html from 'remark-html';
const postsDirectory = path.join(process.cwd(), 'posts')
const postsDirectory = path.join(process.cwd(), 'posts');
export function getSortedPostsData() {
// Get file names under /posts
const fileNames = fs.readdirSync(postsDirectory)
const allPostsData = fileNames.map(fileName => {
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames.map((fileName) => {
// Remove ".md" from file name to get id
const id = fileName.replace(/\.md$/, '')
const id = fileName.replace(/\.md$/, '');
// Read markdown file as string
const fullPath = path.join(postsDirectory, fileName)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const matterResult = matter(fileContents);
// Combine the data with the id
return {
id,
...matterResult.data
}
})
...matterResult.data,
};
});
// Sort posts by date
return allPostsData.sort((a, b) => {
if (a.date < b.date) {
return 1
return 1;
} else {
return -1
return -1;
}
})
});
}
export function getAllPostIds() {
const fileNames = fs.readdirSync(postsDirectory)
return fileNames.map(fileName => {
const fileNames = fs.readdirSync(postsDirectory);
return fileNames.map((fileName) => {
return {
params: {
id: fileName.replace(/\.md$/, '')
}
}
})
id: fileName.replace(/\.md$/, ''),
},
};
});
}
export async function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const matterResult = matter(fileContents);
// Use remark to convert markdown into HTML string
const processedContent = await remark()
.use(html)
.process(matterResult.content)
const contentHtml = processedContent.toString()
.process(matterResult.content);
const contentHtml = processedContent.toString();
// Combine the data with the id and contentHtml
return {
id,
contentHtml,
...matterResult.data
}
...matterResult.data,
};
}

View File

@@ -1,11 +1,8 @@
{
"private": true,
"engines": {
"node": ">=18"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"dev": "next dev",
"start": "next start"
},
"dependencies": {
@@ -16,5 +13,8 @@
"react-dom": "18.2.0",
"remark": "^14.0.2",
"remark-html": "^15.0.1"
},
"engines": {
"node": ">=18"
}
}

View File

@@ -1,5 +1,5 @@
import '../styles/global.css'
import '../styles/global.css';
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
return <Component {...pageProps} />;
}

View File

@@ -1,3 +1,3 @@
export default (req, res) => {
res.status(200).json({ text: 'Hello' })
}
res.status(200).json({ text: 'Hello' });
};

View File

@@ -1,9 +1,9 @@
import Head from 'next/head'
import Layout, { siteTitle } from '../components/layout'
import utilStyles from '../styles/utils.module.css'
import { getSortedPostsData } from '../lib/posts'
import Link from 'next/link'
import Date from '../components/date'
import Head from 'next/head';
import Layout, { siteTitle } from '../components/layout';
import utilStyles from '../styles/utils.module.css';
import { getSortedPostsData } from '../lib/posts';
import Link from 'next/link';
import Date from '../components/date';
export default function Home({ allPostsData }) {
return (
@@ -37,14 +37,14 @@ export default function Home({ allPostsData }) {
</ul>
</section>
</Layout>
)
);
}
export async function getStaticProps() {
const allPostsData = getSortedPostsData()
const allPostsData = getSortedPostsData();
return {
props: {
allPostsData
}
}
allPostsData,
},
};
}

View File

@@ -1,8 +1,8 @@
import Layout from '../../components/layout'
import { getAllPostIds, getPostData } from '../../lib/posts'
import Head from 'next/head'
import Date from '../../components/date'
import utilStyles from '../../styles/utils.module.css'
import Layout from '../../components/layout';
import { getAllPostIds, getPostData } from '../../lib/posts';
import Head from 'next/head';
import Date from '../../components/date';
import utilStyles from '../../styles/utils.module.css';
export default function Post({ postData }) {
return (
@@ -18,22 +18,22 @@ export default function Post({ postData }) {
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
</article>
</Layout>
)
);
}
export async function getStaticPaths() {
const paths = getAllPostIds()
const paths = getAllPostIds();
return {
paths,
fallback: false
}
fallback: false,
};
}
export async function getStaticProps({ params }) {
const postData = await getPostData(params.id)
const postData = await getPostData(params.id);
return {
props: {
postData
}
}
postData,
},
};
}

View File

@@ -2,8 +2,18 @@ html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family:
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
line-height: 1.6;
font-size: 18px;
}

View File

@@ -1 +1 @@
This is a starter template for [Learn Next.js](https://nextjs.org/learn).
This is a starter template for [Learn Next.js](https://nextjs.org/learn).

View File

@@ -1,11 +1,11 @@
import Head from 'next/head'
import Image from 'next/image'
import styles from './layout.module.css'
import utilStyles from '../styles/utils.module.css'
import Link from 'next/link'
import Head from 'next/head';
import Image from 'next/image';
import styles from './layout.module.css';
import utilStyles from '../styles/utils.module.css';
import Link from 'next/link';
const name = '[Your Name]'
export const siteTitle = 'Next.js Sample Website'
const name = '[Your Name]';
export const siteTitle = 'Next.js Sample Website';
export default function Layout({ children, home }) {
return (
@@ -19,7 +19,7 @@ export default function Layout({ children, home }) {
<meta
property="og:image"
content={`https://og-image.vercel.app/${encodeURI(
siteTitle
siteTitle,
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.zeit.co%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
/>
<meta name="og:title" content={siteTitle} />
@@ -65,5 +65,5 @@ export default function Layout({ children, home }) {
</div>
)}
</div>
)
);
}

View File

@@ -1,35 +1,35 @@
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
const postsDirectory = path.join(process.cwd(), 'posts')
const postsDirectory = path.join(process.cwd(), 'posts');
export function getSortedPostsData() {
// Get file names under /posts
const fileNames = fs.readdirSync(postsDirectory)
const allPostsData = fileNames.map(fileName => {
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames.map((fileName) => {
// Remove ".md" from file name to get id
const id = fileName.replace(/\.md$/, '')
const id = fileName.replace(/\.md$/, '');
// Read markdown file as string
const fullPath = path.join(postsDirectory, fileName)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const matterResult = matter(fileContents);
// Combine the data with the id
return {
id,
...matterResult.data
}
})
...matterResult.data,
};
});
// Sort posts by date
return allPostsData.sort((a, b) => {
if (a.date < b.date) {
return 1
return 1;
} else {
return -1
return -1;
}
})
});
}

View File

@@ -1,11 +1,8 @@
{
"private": true,
"engines": {
"node": ">=18"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"dev": "next dev",
"start": "next start"
},
"dependencies": {
@@ -13,5 +10,8 @@
"next": "latest",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"engines": {
"node": ">=18"
}
}

View File

@@ -1,5 +1,5 @@
import '../styles/global.css'
import '../styles/global.css';
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
return <Component {...pageProps} />;
}

View File

@@ -1,7 +1,7 @@
import Head from 'next/head'
import Layout, { siteTitle } from '../components/layout'
import utilStyles from '../styles/utils.module.css'
import { getSortedPostsData } from '../lib/posts'
import Head from 'next/head';
import Layout, { siteTitle } from '../components/layout';
import utilStyles from '../styles/utils.module.css';
import { getSortedPostsData } from '../lib/posts';
export default function Home({ allPostsData }) {
return (
@@ -27,14 +27,14 @@ export default function Home({ allPostsData }) {
</ul>
</section>
</Layout>
)
);
}
export async function getStaticProps() {
const allPostsData = getSortedPostsData()
const allPostsData = getSortedPostsData();
return {
props: {
allPostsData
}
}
allPostsData,
},
};
}

View File

@@ -1,6 +1,6 @@
import Head from 'next/head'
import Link from 'next/link'
import Layout from '../../components/layout'
import Head from 'next/head';
import Link from 'next/link';
import Layout from '../../components/layout';
export default function FirstPost() {
return (
@@ -13,5 +13,5 @@ export default function FirstPost() {
<Link href="/">Back to home</Link>
</h2>
</Layout>
)
);
}

View File

@@ -2,8 +2,18 @@ html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family:
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
line-height: 1.6;
font-size: 18px;
}

View File

@@ -1 +1 @@
This is a starter template for [Learn Next.js](https://nextjs.org/learn).
This is a starter template for [Learn Next.js](https://nextjs.org/learn).

View File

@@ -1,11 +1,11 @@
import Head from 'next/head'
import Image from 'next/image'
import styles from './layout.module.css'
import utilStyles from '../styles/utils.module.css'
import Link from 'next/link'
import Head from 'next/head';
import Image from 'next/image';
import styles from './layout.module.css';
import utilStyles from '../styles/utils.module.css';
import Link from 'next/link';
const name = '[Your Name]'
export const siteTitle = 'Next.js Sample Website'
const name = '[Your Name]';
export const siteTitle = 'Next.js Sample Website';
export default function Layout({ children, home }) {
return (
@@ -19,7 +19,7 @@ export default function Layout({ children, home }) {
<meta
property="og:image"
content={`https://og-image.vercel.app/${encodeURI(
siteTitle
siteTitle,
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.zeit.co%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
/>
<meta name="og:title" content={siteTitle} />
@@ -65,5 +65,5 @@ export default function Layout({ children, home }) {
</div>
)}
</div>
)
);
}

View File

@@ -1,60 +1,60 @@
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
const postsDirectory = path.join(process.cwd(), 'posts')
const postsDirectory = path.join(process.cwd(), 'posts');
export function getSortedPostsData() {
// Get file names under /posts
const fileNames = fs.readdirSync(postsDirectory)
const allPostsData = fileNames.map(fileName => {
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames.map((fileName) => {
// Remove ".md" from file name to get id
const id = fileName.replace(/\.md$/, '')
const id = fileName.replace(/\.md$/, '');
// Read markdown file as string
const fullPath = path.join(postsDirectory, fileName)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const matterResult = matter(fileContents);
// Combine the data with the id
return {
id,
...matterResult.data
}
})
...matterResult.data,
};
});
// Sort posts by date
return allPostsData.sort((a, b) => {
if (a.date < b.date) {
return 1
return 1;
} else {
return -1
return -1;
}
})
});
}
export function getAllPostIds() {
const fileNames = fs.readdirSync(postsDirectory)
return fileNames.map(fileName => {
const fileNames = fs.readdirSync(postsDirectory);
return fileNames.map((fileName) => {
return {
params: {
id: fileName.replace(/\.md$/, '')
}
}
})
id: fileName.replace(/\.md$/, ''),
},
};
});
}
export function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const matterResult = matter(fileContents);
// Combine the data with the id
return {
id,
...matterResult.data
}
...matterResult.data,
};
}

View File

@@ -1,11 +1,8 @@
{
"private": true,
"engines": {
"node": ">=18"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"dev": "next dev",
"start": "next start"
},
"dependencies": {
@@ -13,5 +10,8 @@
"next": "latest",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"engines": {
"node": ">=18"
}
}

View File

@@ -1,5 +1,5 @@
import '../styles/global.css'
import '../styles/global.css';
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
return <Component {...pageProps} />;
}

View File

@@ -1,7 +1,7 @@
import Head from 'next/head'
import Layout, { siteTitle } from '../components/layout'
import utilStyles from '../styles/utils.module.css'
import { getSortedPostsData } from '../lib/posts'
import Head from 'next/head';
import Layout, { siteTitle } from '../components/layout';
import utilStyles from '../styles/utils.module.css';
import { getSortedPostsData } from '../lib/posts';
export default function Home({ allPostsData }) {
return (
@@ -27,14 +27,14 @@ export default function Home({ allPostsData }) {
</ul>
</section>
</Layout>
)
);
}
export async function getStaticProps() {
const allPostsData = getSortedPostsData()
const allPostsData = getSortedPostsData();
return {
props: {
allPostsData
}
}
allPostsData,
},
};
}

View File

@@ -1,5 +1,5 @@
import Layout from '../../components/layout'
import { getAllPostIds, getPostData } from '../../lib/posts'
import Layout from '../../components/layout';
import { getAllPostIds, getPostData } from '../../lib/posts';
export default function Post({ postData }) {
return (
@@ -10,22 +10,22 @@ export default function Post({ postData }) {
<br />
{postData.date}
</Layout>
)
);
}
export async function getStaticPaths() {
const paths = getAllPostIds()
const paths = getAllPostIds();
return {
paths,
fallback: false
}
fallback: false,
};
}
export async function getStaticProps({ params }) {
const postData = getPostData(params.id)
const postData = getPostData(params.id);
return {
props: {
postData
}
}
postData,
},
};
}

View File

@@ -2,8 +2,18 @@ html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family:
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
line-height: 1.6;
font-size: 18px;
}

View File

@@ -1 +1 @@
This is a starter template for [Learn Next.js](https://nextjs.org/learn).
This is a starter template for [Learn Next.js](https://nextjs.org/learn).

View File

@@ -1,16 +1,16 @@
{
"private": true,
"engines": {
"node": ">=18"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"dev": "next dev",
"start": "next start"
},
"dependencies": {
"next": "latest",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"engines": {
"node": ">=18"
}
}

View File

@@ -92,8 +92,15 @@ export default function Home() {
border-radius: 5px;
padding: 0.75rem;
font-size: 1.1rem;
font-family: Menlo, Monaco, Lucida Console, Liberation Mono,
DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
font-family:
Menlo,
Monaco,
Lucida Console,
Liberation Mono,
DejaVu Sans Mono,
Bitstream Vera Sans Mono,
Courier New,
monospace;
}
`}</style>
@@ -102,8 +109,17 @@ export default function Home() {
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue,
font-family:
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
}
* {
@@ -111,5 +127,5 @@ export default function Home() {
}
`}</style>
</div>
)
);
}

View File

@@ -33,7 +33,6 @@
text-align: center;
}
.description {
line-height: 1.5;
font-size: 1.5rem;
@@ -58,7 +57,9 @@
text-decoration: none;
border: 1px solid #eaeaea;
border-radius: 10px;
transition: color 0.15s ease, border-color 0.15s ease;
transition:
color 0.15s ease,
border-color 0.15s ease;
}
.card:hover,

View File

@@ -2,8 +2,19 @@ html,
body {
padding: 0;
margin: 0;
font-family: Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
}
a {

View File

@@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2022 Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1 +1 @@
This is a starter template for [Learn Next.js](https://nextjs.org/learn).
This is a starter template for [Learn Next.js](https://nextjs.org/learn).

View File

@@ -1,16 +1,16 @@
{
"private": true,
"engines": {
"node": ">=18"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"dev": "next dev",
"start": "next start"
},
"dependencies": {
"next": "latest",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"engines": {
"node": ">=18"
}
}

View File

@@ -1,4 +1,4 @@
import Head from 'next/head'
import Head from 'next/head';
import styles from '../styles/Home.module.css';
export default function Home() {
@@ -92,8 +92,15 @@ export default function Home() {
border-radius: 5px;
padding: 0.75rem;
font-size: 1.1rem;
font-family: Menlo, Monaco, Lucida Console, Liberation Mono,
DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
font-family:
Menlo,
Monaco,
Lucida Console,
Liberation Mono,
DejaVu Sans Mono,
Bitstream Vera Sans Mono,
Courier New,
monospace;
}
`}</style>
@@ -102,8 +109,17 @@ export default function Home() {
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue,
font-family:
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
}
* {
@@ -111,5 +127,5 @@ export default function Home() {
}
`}</style>
</div>
)
);
}

View File

@@ -33,7 +33,6 @@
text-align: center;
}
.description {
line-height: 1.5;
font-size: 1.5rem;
@@ -58,7 +57,9 @@
text-decoration: none;
border: 1px solid #eaeaea;
border-radius: 10px;
transition: color 0.15s ease, border-color 0.15s ease;
transition:
color 0.15s ease,
border-color 0.15s ease;
}
.card:hover,

View File

@@ -2,8 +2,19 @@ html,
body {
padding: 0;
margin: 0;
font-family: Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
}
a {

View File

@@ -1,17 +0,0 @@
{
"private": true,
"engines": {
"node": ">=18"
},
"license": "MIT",
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
}
},
"devDependencies": {
"prettier": "^2.0.2",
"pretty-quick": "2.0.1",
"husky": "4.2.3"
}
}

View File

@@ -1,12 +1,12 @@
// Example: Adding className with <Link>
import Link from 'next/link'
import Link from 'next/link';
export default function LinkClassnameExample() {
return (
<Link href="/" className="foo" target="_blank" rel="noopener noreferrer">
Hello World
</Link>
)
);
}
// Take a look at https://nextjs.org/docs/api-reference/next/link

View File

@@ -1 +1 @@
This is a starter template for [Learn Next.js](https://nextjs.org/learn).
This is a starter template for [Learn Next.js](https://nextjs.org/learn).

View File

@@ -1,6 +1,6 @@
import { parseISO, format } from 'date-fns'
import { parseISO, format } from 'date-fns';
export default function Date({ dateString }: { dateString: string }) {
const date = parseISO(dateString)
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>
const date = parseISO(dateString);
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>;
}

View File

@@ -1,18 +1,18 @@
import Head from 'next/head'
import Image from 'next/image'
import styles from './layout.module.css'
import utilStyles from '../styles/utils.module.css'
import Link from 'next/link'
import Head from 'next/head';
import Image from 'next/image';
import styles from './layout.module.css';
import utilStyles from '../styles/utils.module.css';
import Link from 'next/link';
const name = '[Your Name]'
export const siteTitle = 'Next.js Sample Website'
const name = '[Your Name]';
export const siteTitle = 'Next.js Sample Website';
export default function Layout({
children,
home
home,
}: {
children: React.ReactNode
home?: boolean
children: React.ReactNode;
home?: boolean;
}) {
return (
<div className={styles.container}>
@@ -25,7 +25,7 @@ export default function Layout({
<meta
property="og:image"
content={`https://og-image.vercel.app/${encodeURI(
siteTitle
siteTitle,
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.zeit.co%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
/>
<meta name="og:title" content={siteTitle} />
@@ -71,5 +71,5 @@ export default function Layout({
</div>
)}
</div>
)
);
}

View File

@@ -1,4 +1,4 @@
declare module 'remark-html' {
const html: any
export default html
const html: any;
export default html;
}

View File

@@ -1,69 +1,69 @@
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { remark } from 'remark'
import html from 'remark-html'
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { remark } from 'remark';
import html from 'remark-html';
const postsDirectory = path.join(process.cwd(), 'posts')
const postsDirectory = path.join(process.cwd(), 'posts');
export function getSortedPostsData() {
// Get file names under /posts
const fileNames = fs.readdirSync(postsDirectory)
const allPostsData = fileNames.map(fileName => {
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames.map((fileName) => {
// Remove ".md" from file name to get id
const id = fileName.replace(/\.md$/, '')
const id = fileName.replace(/\.md$/, '');
// Read markdown file as string
const fullPath = path.join(postsDirectory, fileName)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const matterResult = matter(fileContents);
// Combine the data with the id
return {
id,
...(matterResult.data as { date: string; title: string })
}
})
...(matterResult.data as { date: string; title: string }),
};
});
// Sort posts by date
return allPostsData.sort((a, b) => {
if (a.date < b.date) {
return 1
return 1;
} else {
return -1
return -1;
}
})
});
}
export function getAllPostIds() {
const fileNames = fs.readdirSync(postsDirectory)
return fileNames.map(fileName => {
const fileNames = fs.readdirSync(postsDirectory);
return fileNames.map((fileName) => {
return {
params: {
id: fileName.replace(/\.md$/, '')
}
}
})
id: fileName.replace(/\.md$/, ''),
},
};
});
}
export async function getPostData(id: string) {
const fullPath = path.join(postsDirectory, `${id}.md`)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const matterResult = matter(fileContents);
// Use remark to convert markdown into HTML string
const processedContent = await remark()
.use(html)
.process(matterResult.content)
const contentHtml = processedContent.toString()
.process(matterResult.content);
const contentHtml = processedContent.toString();
// Combine the data with the id and contentHtml
return {
id,
contentHtml,
...(matterResult.data as { date: string; title: string })
}
...(matterResult.data as { date: string; title: string }),
};
}

View File

@@ -1,11 +1,8 @@
{
"private": true,
"engines": {
"node": ">=18"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"dev": "next dev",
"start": "next start"
},
"dependencies": {
@@ -21,5 +18,8 @@
"@types/node": "^18.11.9",
"@types/react": "^18.0.25",
"typescript": "^4.8.4"
},
"engines": {
"node": ">=18"
}
}

View File

@@ -1,6 +1,6 @@
import '../styles/global.css'
import { AppProps } from 'next/app'
import '../styles/global.css';
import { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
return <Component {...pageProps} />;
}

View File

@@ -1,5 +1,5 @@
import { NextApiRequest, NextApiResponse } from 'next'
import { NextApiRequest, NextApiResponse } from 'next';
export default (_: NextApiRequest, res: NextApiResponse) => {
res.status(200).json({ text: 'Hello' })
}
res.status(200).json({ text: 'Hello' });
};

View File

@@ -1,19 +1,19 @@
import Head from 'next/head'
import Layout, { siteTitle } from '../components/layout'
import utilStyles from '../styles/utils.module.css'
import { getSortedPostsData } from '../lib/posts'
import Link from 'next/link'
import Date from '../components/date'
import { GetStaticProps } from 'next'
import Head from 'next/head';
import Layout, { siteTitle } from '../components/layout';
import utilStyles from '../styles/utils.module.css';
import { getSortedPostsData } from '../lib/posts';
import Link from 'next/link';
import Date from '../components/date';
import { GetStaticProps } from 'next';
export default function Home({
allPostsData
allPostsData,
}: {
allPostsData: {
date: string
title: string
id: string
}[]
date: string;
title: string;
id: string;
}[];
}) {
return (
<Layout home>
@@ -42,14 +42,14 @@ export default function Home({
</ul>
</section>
</Layout>
)
);
}
export const getStaticProps: GetStaticProps = async () => {
const allPostsData = getSortedPostsData()
const allPostsData = getSortedPostsData();
return {
props: {
allPostsData
}
}
}
allPostsData,
},
};
};

View File

@@ -1,18 +1,18 @@
import Layout from '../../components/layout'
import { getAllPostIds, getPostData } from '../../lib/posts'
import Head from 'next/head'
import Date from '../../components/date'
import utilStyles from '../../styles/utils.module.css'
import { GetStaticProps, GetStaticPaths } from 'next'
import Layout from '../../components/layout';
import { getAllPostIds, getPostData } from '../../lib/posts';
import Head from 'next/head';
import Date from '../../components/date';
import utilStyles from '../../styles/utils.module.css';
import { GetStaticProps, GetStaticPaths } from 'next';
export default function Post({
postData
postData,
}: {
postData: {
title: string
date: string
contentHtml: string
}
title: string;
date: string;
contentHtml: string;
};
}) {
return (
<Layout>
@@ -27,22 +27,22 @@ export default function Post({
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
</article>
</Layout>
)
);
}
export const getStaticPaths: GetStaticPaths = async () => {
const paths = getAllPostIds()
const paths = getAllPostIds();
return {
paths,
fallback: false
}
}
fallback: false,
};
};
export const getStaticProps: GetStaticProps = async ({ params }) => {
const postData = await getPostData(params?.id as string)
const postData = await getPostData(params?.id as string);
return {
props: {
postData
}
}
}
postData,
},
};
};

View File

@@ -2,8 +2,18 @@ html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family:
-apple-system,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Oxygen,
Ubuntu,
Cantarell,
Fira Sans,
Droid Sans,
Helvetica Neue,
sans-serif;
line-height: 1.6;
font-size: 18px;
}