Skip to content

Commit a783196

Browse files
committed
added images example
1 parent c03c03a commit a783196

File tree

24 files changed

+379
-6
lines changed

24 files changed

+379
-6
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
test:
2121
strategy:
2222
matrix:
23-
node-version: [14, 16, 17, 18, 19, 20]
23+
node-version: [16, 17, 18, 19, 20]
2424
os: [ubuntu-latest, windows-latest]
2525
runs-on: ${{ matrix.os }}
2626
steps:
@@ -52,10 +52,22 @@ jobs:
5252
- run: yarn build
5353
working-directory: examples/next-rsc-dynamic
5454

55+
build-example-next-images-example:
56+
strategy:
57+
matrix:
58+
node-version: [17, 18, 19, 20] # `app` dir requires 17+
59+
os: [ubuntu-latest, windows-latest]
60+
runs-on: ${{ matrix.os }}
61+
steps:
62+
- uses: schickling-actions/checkout-and-install@main
63+
- run: yarn build
64+
- run: yarn build
65+
working-directory: examples/next-images
66+
5567
build-example-node-script:
5668
strategy:
5769
matrix:
58-
node-version: [14, 16, 17, 18, 19, 20]
70+
node-version: [16, 17, 18, 19, 20]
5971
os: [ubuntu-latest, windows-latest]
6072
runs-on: ${{ matrix.os }}
6173
steps:
@@ -67,7 +79,7 @@ jobs:
6779
build-example-node-script-mdx:
6880
strategy:
6981
matrix:
70-
node-version: [14, 16, 17, 18, 19, 20]
82+
node-version: [16, 17, 18, 19, 20]
7183
os: [ubuntu-latest, windows-latest]
7284
runs-on: ${{ matrix.os }}
7385
steps:
@@ -79,7 +91,7 @@ jobs:
7991
build-example-node-script-remote-content:
8092
strategy:
8193
matrix:
82-
node-version: [14, 16, 17, 18, 19, 20]
94+
node-version: [16, 17, 18, 19, 20]
8395
os: [ubuntu-latest, windows-latest]
8496
runs-on: ${{ matrix.os }}
8597
steps:

examples/next-images/.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# dependencies
2+
node_modules
3+
4+
# next
5+
dist
6+
.next
7+
8+
# contentlayer
9+
.contentlayer
10+
11+
# yarn
12+
yarn.lock
13+
yarn-error.log
14+
15+
# mac
16+
.DS_Store

examples/next-images/app/layout.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import '../styles/globals.css'
2+
3+
import { Header } from '../components/Header'
4+
5+
export default function RootLayout({ children }: { children: React.ReactNode }) {
6+
return (
7+
<html>
8+
<head>
9+
<title>Contentlayer Next.js Example</title>
10+
<link rel="icon" type="image/x-icon" href="/favicon.png" />
11+
</head>
12+
<body>
13+
<Header />
14+
<div className="px-6">{children}</div>
15+
</body>
16+
</html>
17+
)
18+
}

examples/next-images/app/page.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import Link from "next/link";
2+
import { compareDesc, format, parseISO } from "date-fns";
3+
import { allPosts, Post } from "contentlayer/generated";
4+
import { getMDXComponent } from "next-contentlayer/hooks";
5+
6+
function PostCard(post: Post) {
7+
const Content = getMDXComponent(post.body.code);
8+
9+
return (
10+
<div className="mb-8">
11+
<h2 className="text-xl">
12+
<Link
13+
href={post.url}
14+
className="text-blue-700 hover:text-blue-900"
15+
legacyBehavior>
16+
{post.title}
17+
</Link>
18+
</h2>
19+
<time dateTime={post.date} className="block mb-2 text-xs text-gray-600">
20+
{format(parseISO(post.date), "LLLL d, yyyy")}
21+
</time>
22+
<div className="text-sm">
23+
<Content />
24+
</div>
25+
</div>
26+
);
27+
}
28+
29+
export default function Home() {
30+
const posts = allPosts.sort((a, b) =>
31+
compareDesc(new Date(a.date), new Date(b.date))
32+
);
33+
34+
return (
35+
<div className="max-w-xl py-8 mx-auto">
36+
<h1 className="mb-8 text-3xl font-bold text-center">Next.js Example</h1>
37+
38+
{posts.map((post, idx) => (
39+
<PostCard key={idx} {...post} />
40+
))}
41+
</div>
42+
);
43+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { format, parseISO } from 'date-fns'
2+
import { allPosts } from 'contentlayer/generated'
3+
import { getMDXComponent } from 'next-contentlayer/hooks'
4+
import Image from 'next/image'
5+
6+
export const generateStaticParams = async () => allPosts.map((post) => ({ slug: post._raw.flattenedPath }))
7+
8+
export const generateMetadata = ({ params }) => {
9+
const post = allPosts.find((post) => post._raw.flattenedPath === params.slug)
10+
return { title: post.title }
11+
}
12+
13+
const PostLayout = ({ params }: { params: { slug: string } }) => {
14+
const post = allPosts.find((post) => post._raw.flattenedPath === params.slug)
15+
16+
const Content = getMDXComponent(post.body.code)
17+
18+
return (
19+
<article className="py-8 mx-auto max-w-xl space-y-4">
20+
{post.cover && (
21+
<Image
22+
src={post.cover.filePath.replace('../public', '')}
23+
alt=""
24+
width={500}
25+
height={500 / post.cover.aspectRatio}
26+
blurDataURL={post.cover.blurhashDataUrl}
27+
/>
28+
)}
29+
<div className="mb-8 text-center">
30+
<time dateTime={post.date} className="mb-1 text-xs text-gray-600">
31+
{format(parseISO(post.date), 'LLLL d, yyyy')}
32+
</time>
33+
<h1>{post.title}</h1>
34+
</div>
35+
<Content />
36+
</article>
37+
)
38+
}
39+
40+
export default PostLayout
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { FC } from 'react'
2+
import React from 'react'
3+
4+
export const Button: FC<{ title: string }> = ({ title }) => (
5+
<div
6+
style={{ padding: 10, backgroundColor: '#333', color: '#fff', display: 'inline-block', borderRadius: 4 }}
7+
onClick={() => alert('Hi')}
8+
>
9+
{title}
10+
</div>
11+
)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import Link from 'next/link'
2+
3+
function Icon() {
4+
return (
5+
<svg width="22" height="24" viewBox="0 0 22 24" fill="none" xmlns="http://www.w3.org/2000/svg">
6+
<path
7+
fillRule="evenodd"
8+
clipRule="evenodd"
9+
d="M10.43 0.92268C11.1426 0.398115 12.1177 0.407491 12.82 0.945665L19.9928 6.44198C21.0266 7.23419 21.0266 8.78771 19.9928 9.57992L17.2573 11.6761L20.0379 13.9037C21.0493 14.7139 21.022 16.2574 19.9826 17.0315L12.62 22.5153C11.8634 23.0788 10.8134 23.0332 10.1089 22.4063L4.34789 17.2802L3.54224 16.5903C-0.0530112 13.5114 0.390183 7.84094 4.41274 5.35212L10.43 0.92268ZM16.1955 10.8254L12.8515 8.14659C12.1375 7.57457 11.1235 7.56365 10.3972 8.12017L7.92298 10.0161C6.88913 10.8084 6.88913 12.3619 7.92298 13.1541L10.4154 15.064C11.129 15.6108 12.1224 15.6108 12.836 15.064L16.1773 12.5036L19.2086 14.932C19.5457 15.2021 19.5366 15.7166 19.1901 15.9747L11.8275 21.4585C11.5753 21.6463 11.2253 21.6311 10.9905 21.4221L5.2248 16.2918L4.40495 15.5895C1.48255 13.0869 1.84941 8.47338 5.13088 6.46078L5.15471 6.44617L11.2165 1.98398C11.454 1.80913 11.779 1.81225 12.0132 1.99164L19.1859 7.48796C19.5305 7.75203 19.5305 8.26987 19.1859 8.53394L16.1955 10.8254ZM15.1155 11.653L12.0291 14.018C11.7913 14.2003 11.4601 14.2003 11.2223 14.018L8.72984 12.1081C8.38523 11.844 8.38523 11.3262 8.72984 11.0621L11.2041 9.16615C11.4462 8.98065 11.7842 8.98429 12.0222 9.17496L15.1155 11.653Z"
10+
fill="#7C3AED"
11+
stroke="#7C3AED"
12+
strokeWidth="0.5"
13+
></path>
14+
</svg>
15+
)
16+
}
17+
18+
function Logo() {
19+
return (
20+
<Link href="/" className="inline-flex justify-center items-center">
21+
<span className="mr-2">
22+
<Icon />
23+
</span>
24+
<span className="font-bold">Contentlayer</span>
25+
</Link>
26+
)
27+
}
28+
29+
export function Header() {
30+
return (
31+
<header className="p-8 flex justify-center">
32+
<Logo />
33+
</header>
34+
)
35+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { defineDocumentType, makeSource } from 'contentlayer/source-files'
2+
3+
const Post = defineDocumentType(() => ({
4+
name: 'Post',
5+
filePathPattern: `**/*.mdx`,
6+
contentType: 'mdx',
7+
fields: {
8+
title: {
9+
type: 'string',
10+
description: 'The title of the post',
11+
required: true,
12+
},
13+
date: {
14+
type: 'date',
15+
description: 'The date of the post',
16+
required: true,
17+
},
18+
cover: {
19+
type: 'image',
20+
required: false,
21+
},
22+
},
23+
computedFields: {
24+
url: {
25+
type: 'string',
26+
resolve: (doc) => `/posts/${doc._raw.flattenedPath}`,
27+
},
28+
},
29+
}))
30+
31+
export default makeSource({
32+
contentDirPath: 'posts',
33+
documentTypes: [Post],
34+
})

examples/next-images/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.

examples/next-images/next.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const { withContentlayer } = require("next-contentlayer");
2+
3+
/** @type {import('next').NextConfig} */
4+
const nextConfig = {
5+
experimental: {
6+
appDir: true,
7+
},
8+
};
9+
10+
module.exports = withContentlayer(nextConfig);

examples/next-images/package.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "next-images",
3+
"version": "0.1.0",
4+
"private": true,
5+
"scripts": {
6+
"dev": "next dev",
7+
"build": "next build",
8+
"start": "next start"
9+
},
10+
"dependencies": {
11+
"contentlayer": "latest",
12+
"date-fns": "2.30.0",
13+
"next": "13.4.7",
14+
"next-contentlayer": "latest",
15+
"react": "18.2.0",
16+
"react-dom": "18.2.0"
17+
},
18+
"devDependencies": {
19+
"@types/react": "18.2.7",
20+
"autoprefixer": "^10.4.14",
21+
"postcss": "^8.4.24",
22+
"tailwindcss": "^3.3.2",
23+
"typescript": "5.1.5"
24+
}
25+
}
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+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: Change me!
3+
date: 2022-03-11
4+
cover: '../public/images/mark-neal-unsplash.jpg'
5+
---
6+
7+
When you change a source file, Contentlayer automatically updates the content cache, which prompts Next.js to reload the content on screen.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
title: Click me!
3+
date: 2022-02-28
4+
---
5+
6+
Blog posts have their own pages. The content source is a markdown file, parsed to HTML by Contentlayer.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
title: What is Contentlayer?
3+
date: 2022-02-22
4+
---
5+
6+
**Contentlayer makes working with content easy.** It is a content preprocessor that validates and transforms your content into type-safe JSON you can easily import into your application.
2.19 KB
Loading
Loading
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;700&display=swap");
2+
3+
@tailwind base;
4+
@tailwind components;
5+
@tailwind utilities;
6+
7+
p {
8+
@apply mb-4;
9+
}
10+
11+
h1,
12+
h2,
13+
h3,
14+
h4,
15+
h5,
16+
h6 {
17+
@apply font-bold
18+
mb-1;
19+
}
20+
21+
h1 {
22+
@apply text-3xl;
23+
}
24+
25+
h2 {
26+
@apply text-xl;
27+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const defaultTheme = require("tailwindcss/defaultTheme");
2+
3+
module.exports = {
4+
content: [
5+
"./app/**/*.{js,ts,jsx,tsx}",
6+
"./pages/**/*.{js,ts,jsx,tsx}",
7+
"./components/**/*.{js,ts,jsx,tsx}",
8+
],
9+
theme: {
10+
extend: {
11+
fontFamily: {
12+
sans: ["Inter", ...defaultTheme.fontFamily.sans],
13+
},
14+
},
15+
},
16+
plugins: [],
17+
};

0 commit comments

Comments
 (0)