chalknotes 0.0.23 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,154 @@
1
+ # ✏️ ChalkNotes
2
+
3
+ **Turn your Notion database into a blog with zero config. Works with Next.js Page Router and App Router.**
4
+
5
+ ---
6
+
7
+ ## 🚀 Features
8
+
9
+ - 📄 Fetch blog posts from Notion
10
+ - 🪄 Auto-generate routes for App Router or Page Router
11
+ - ⚙️ Helpers for `getStaticProps` / `getStaticPaths`
12
+ - 🧠 Minimal setup – just run `chalknotes`
13
+
14
+ ---
15
+
16
+ ## 📦 Installation
17
+
18
+ ```bash
19
+ pnpm add chalknotes
20
+ # or
21
+ npm install chalknotes
22
+ ```
23
+
24
+ ---
25
+
26
+ ## 🧙‍♂️ Quick Start
27
+
28
+ ```bash
29
+ npx chalknotes
30
+ ```
31
+
32
+ - Automatically detects if you're using **App Router** or **Page Router**
33
+ - Generates blog routes at `/blog/[slug]`
34
+ - You’re done ✅
35
+
36
+ ---
37
+
38
+ ## 🔧 Setup
39
+
40
+ Make sure your `.env` file contains:
41
+
42
+ ```env
43
+ NOTION_TOKEN=secret_...
44
+ NOTION_DATABASE_ID=xxxxxxxxxxxxxxxxxxxxxx
45
+ ```
46
+
47
+ Your Notion database should have:
48
+ - A **"Name"** title property
49
+ - A **"Published"** checkbox property
50
+
51
+ ---
52
+
53
+ ## 📚 Usage in Next.js
54
+
55
+ ### Page Router
56
+
57
+ Creates:
58
+
59
+ ```js
60
+ // pages/blog/[slug].js
61
+ import { getStaticPropsForPost, getStaticPathsForPosts } from 'chalknotes';
62
+
63
+ export const getStaticProps = getStaticPropsForPost;
64
+ export const getStaticPaths = getStaticPathsForPosts;
65
+
66
+ export default function BlogPost({ post }) {
67
+ return (
68
+ <article>
69
+ <h1>{post.title}</h1>
70
+ <div dangerouslySetInnerHTML={{ __html: post.content }} />
71
+ </article>
72
+ );
73
+ }
74
+ ```
75
+
76
+ ---
77
+
78
+ ### App Router
79
+
80
+ Creates:
81
+
82
+ ```jsx
83
+ // app/blog/[slug]/page.jsx
84
+ import { getPostBySlug } from 'chalknotes';
85
+
86
+ export default async function BlogPost({ params }) {
87
+ const post = await getPostBySlug(params.slug);
88
+
89
+ return (
90
+ <article>
91
+ <h1>{post.title}</h1>
92
+ <div dangerouslySetInnerHTML={{ __html: post.content }} />
93
+ </article>
94
+ );
95
+ }
96
+ ```
97
+
98
+ ---
99
+
100
+ ## 🧩 API
101
+
102
+ ### `getPostBySlug(slug: string)`
103
+ Fetches a post and renders Notion blocks as HTML.
104
+
105
+ ```js
106
+ const post = await getPostBySlug('my-post-title');
107
+ ```
108
+
109
+ ---
110
+
111
+ ### `getAllPosts()`
112
+ Returns all published posts with metadata:
113
+
114
+ ```js
115
+ [
116
+ {
117
+ title: "My First Post",
118
+ slug: "my-first-post",
119
+ notionPageId: "xxxxxxxx"
120
+ },
121
+ ...
122
+ ]
123
+ ```
124
+
125
+ ---
126
+
127
+ ### `getStaticPropsForPost()`
128
+ For use with `getStaticProps` in Page Router.
129
+
130
+ ---
131
+
132
+ ### `getStaticPathsForPosts()`
133
+ For use with `getStaticPaths` in Page Router.
134
+
135
+ ---
136
+
137
+ ## 📅 Roadmap
138
+
139
+ - [ ] Rich block support (images, lists, toggles, etc)
140
+ - [ ] RSS feed support
141
+ - [ ] MDX or Markdown output option
142
+ - [ ] Custom blog.config.js support
143
+
144
+ ---
145
+
146
+ ## 💡 Inspiration
147
+
148
+ Built to scratch an itch while exploring the simplicity of tools like [feather.so](https://feather.so/) and [Notion Blog](https://github.com/ijjk/notion-blog).
149
+
150
+ ---
151
+
152
+ ## 🧑‍💻 Author
153
+
154
+ [NepTune](https://github.com/yourhandle) • MIT License
package/bin/cli.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  const fs = require("fs");
3
3
  const path = require("path");
4
4
 
@@ -22,9 +22,9 @@ export const getStaticPaths = getStaticPathsForPosts;
22
22
 
23
23
  export default function BlogPost({ post }) {
24
24
  return (
25
- <article>
26
- <h1>{post.title}</h1>
27
- <div dangerouslySetInnerHTML={{ __html: post.content }} />
25
+ <article className="max-w-4xl mx-auto px-4 py-8">
26
+ <h1 className="text-3xl font-bold mb-4">{post.title}</h1>
27
+ <div className="text-lg text-gray-700" dangerouslySetInnerHTML={{ __html: post.content }} />
28
28
  </article>
29
29
  );
30
30
  }
@@ -44,9 +44,9 @@ export default async function BlogPost({ params }) {
44
44
  const post = await getPostBySlug(params.slug);
45
45
 
46
46
  return (
47
- <article>
48
- <h1>{post.title}</h1>
49
- <div dangerouslySetInnerHTML={{ __html: post.content }} />
47
+ <article className="max-w-4xl mx-auto px-4 py-8">
48
+ <h1 className="text-3xl font-bold mb-4">{post.title}</h1>
49
+ <div className="text-lg text-gray-700" dangerouslySetInnerHTML={{ __html: post.content }} />
50
50
  </article>
51
51
  );
52
52
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chalknotes",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "description": "A tool that simplifies blogs.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -1,7 +1,10 @@
1
1
  const { getAllPosts } = require('./lib/getAllPosts');
2
2
  const { getPostBySlug } = require('./lib/getPostBySlug');
3
+ const { getStaticPropsForPost, getStaticPathsForPosts } = require('./lib/nextHelpers');
3
4
 
4
5
  module.exports = {
5
6
  getAllPosts,
6
- getPostBySlug
7
+ getPostBySlug,
8
+ getStaticPropsForPost,
9
+ getStaticPathsForPosts
7
10
  }
@@ -27,22 +27,21 @@ const getPostBySlug = async (slug) => {
27
27
  switch (block.type) {
28
28
  case "paragraph":
29
29
  const textHTML = block.paragraph.rich_text.map(text => text.plain_text).join("");
30
- content += `<p>${textHTML}</p>`
30
+ content += `<p class="mb-4">${textHTML}</p>`
31
31
  break;
32
32
  case "heading_1":
33
33
  const headingHTML = block.heading_1.rich_text.map(text => text.plain_text).join("");
34
- content += `<h1>${headingHTML}</h1>`
34
+ content += `<h1 class="text-2xl font-bold mb-4">${headingHTML}</h1>`
35
35
  break;
36
36
  case "heading_2":
37
37
  const heading2HTML = block.heading_2.rich_text.map(text => text.plain_text).join("");
38
- content += `<h2>${heading2HTML}</h2>`
38
+ content += `<h2 class="text-xl font-bold mb-4">${heading2HTML}</h2>`
39
39
  break;
40
40
  case "heading_3":
41
41
  const heading3HTML = block.heading_3.rich_text.map(text => text.plain_text).join("");
42
- content += `<h3>${heading3HTML}</h3>`
42
+ content += `<h3 class="text-lg font-bold mb-4">${heading3HTML}</h3>`
43
43
  break;
44
44
  }
45
- console.log(content)
46
45
  }
47
46
  return {
48
47
  title,
@@ -0,0 +1,36 @@
1
+ const { getAllPosts } = require('./getAllPosts');
2
+ const { getPostBySlug } = require('./getPostBySlug');
3
+
4
+ /**
5
+ * Provides static props for a post page using slug
6
+ */
7
+ const getStaticPropsForPost = async ({ params }) => {
8
+ const post = await getPostBySlug(params.slug);
9
+
10
+ return {
11
+ props: {
12
+ post
13
+ }
14
+ };
15
+ };
16
+
17
+ /**
18
+ * Provides static paths for all blog posts
19
+ */
20
+ const getStaticPathsForPosts = async () => {
21
+ const posts = await getAllPosts();
22
+
23
+ const paths = posts.map((post) => ({
24
+ params: { slug: post.slug }
25
+ }));
26
+
27
+ return {
28
+ paths,
29
+ fallback: false,
30
+ };
31
+ };
32
+
33
+ module.exports = {
34
+ getStaticPropsForPost,
35
+ getStaticPathsForPosts
36
+ };