Skip to content

Commit 6427854

Browse files
authored
Merge pull request #42 from thedevdavid/release/0.7.0
Release/0.7.0
2 parents 5d859ba + 35f06e5 commit 6427854

Some content is hidden

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

41 files changed

+1665
-1571
lines changed

.env.example

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
#Next
22
NEXT_PUBLIC_BASE_URL=https://localhost:3000
33

4-
#Analytics
4+
#Umami Analytics
55
NEXT_PUBLIC_UMAMI_SCRIPT_URL=
66
NEXT_PUBLIC_UMAMI_WEBSITE_ID=
77

8+
#Plausible Analytics
9+
NEXT_PUBLIC_PLAUSIBLE_DOMAIN=
10+
NEXT_PUBLIC_PLAUSIBLE_SCRIPT_URL=
11+
812
#Email
913
EMAIL_API_BASE=
1014
NEXT_PUBLIC_EMAIL_API_KEY=

CHANGELOG.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.7.0] - 2023-08-19
11+
1012
### Added
1113

12-
- Convertkit newsletter provider
1314
- Plausible analytics provider
15+
- Math and Katex support
16+
- Author content definition
17+
- Tweet MDX component
18+
- YT Video MDX component
19+
- Newsletter CTA MDX component
20+
- Documentation updates
21+
- Announcement banner
22+
23+
### Changed
24+
25+
- Small SEO updates
26+
- Codebase and type fixes
27+
- Design updates
1428

1529
## [0.6.0] - 2023-07-16
1630

README.md

+52-14
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
![Image2](/screenshots/garden2.png)
44
[More screenshots here](/screenshots/)
55

6-
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/thedevdavid/digital-garden)
6+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fthedevdavid%2Fdigital-garden%2F)
77

88
An open source blogging (digital gardening) template for developers using [Next.js](https://nextjs.org/) app router, MDX, [Contentlayer](https://contentlayer.dev/), [Tailwind CSS](https://tailwindcss.com/), [@shadcn/ui](https://ui.shadcn.com/) , [Lucide Icons](https://lucide.dev/icons), and more.
99

@@ -18,14 +18,18 @@ If you love this template and/or use it, please give it a star on GitHub. This w
1818
- [Motivation](#motivation)
1919
- [Getting Started](#getting-started)
2020
- [Writing content](#writing-content)
21+
- [Frontmatter](#frontmatter)
2122
- [Deployment](#deployment)
2223
- [Customization](#customization)
2324
- [Fonts](#fonts)
2425
- [Colors](#colors)
2526
- [Metadata](#metadata)
27+
- [Navigation](#navigation)
28+
- [Social links](#social-links)
2629
- [Analytics](#analytics)
2730
- [Vercel](#vercel)
2831
- [Umami](#umami)
32+
- [Plausible](#plausible)
2933
- [Other analytics providers](#other-analytics-providers)
3034
- [Newsletter subscription](#newsletter-subscription)
3135
- [MailerLite](#mailerlite)
@@ -73,6 +77,19 @@ Editing list pages is done in the `lib` folder.
7377
- `/projects` - `lib/projects-data.ts`
7478
- `/social` - `lib/social-data.ts`
7579

80+
#### Frontmatter
81+
82+
Frontmatter is used to define metadata for pages and posts. It's located at the top of the file and is written in YAML. You can define the following fields:
83+
84+
- `title` - The title of the page/post
85+
- `description` - The description of the page/post
86+
- `publishedDate` - The date of the post (not used on pages)
87+
- `lastUpdatedDate` - The date of the page/post
88+
- `tags` - List of tags for the post. You can add new tags by adding them to the `tagOptions` list. (not used on pages)
89+
- `series` - The series of the post. A series has a title and an order number for a post. (not used on pages)
90+
- `author` - The author of the post. An author has a name, and image. (not used on pages)
91+
- `status` - Whether the page/post is published or draft
92+
7693
### Deployment
7794

7895
You can deploy the project with [Vercel](https://vercel.com/) or any other hosting provider. If you want to use Vercel, you can use the button at the top of this README.
@@ -106,8 +123,14 @@ Images and other media files are located in `public/` directory. You can use the
106123

107124
You can change the metadata and author details in `utils/metadata.ts`. This will be used around the site for titles, social links, social handles, SEO, etc.
108125

126+
#### Navigation
127+
109128
You can edit navigation links in `lib/navigation-links.ts`.
110129

130+
#### Social links
131+
132+
You can edit social links in `lib/social-data.ts`. You can also add new social links by adding them to the file. Using the platform name as the key and the URL as the value. The `SocialButton` component will automatically add the icon for the platform if it's supported in [simple-icons](https://simpleicons.org/).
133+
111134
### Analytics
112135

113136
#### Vercel
@@ -121,6 +144,13 @@ Umami is a simple, easy to use, web analytics solution with self-hosting option!
121144
Configure:
122145
Set `NEXT_PUBLIC_UMAMI_SCRIPT_URL` & `NEXT_PUBLIC_UMAMI_WEBSITE_ID` environment variables on your `.env.local` file and on Vercel dashboard.
123146

147+
#### Plausible
148+
149+
Plausible is a simple, lightweight, open-source alternative to Google Analytics. You can read more about it on [Plausible website](https://plausible.io/).
150+
151+
Configure:
152+
Set `NEXT_PUBLIC_PLAUSIBLE_DOMAIN` & `NEXT_PUBLIC_PLAUSIBLE_SCRIPT_URL` environment variables on your `.env.local` file and on Vercel dashboard. If you're concerned about ad blockers, you can proxy the plausible script through your own domain. You can read more about it [here](https://plausible.io/docs/proxy/guides/nextjs).
153+
124154
#### Other analytics providers
125155

126156
Supporting other analytics providers are in progress. Feel free to open an issue if you have any suggestions or a PR if you want to implement it yourself.
@@ -151,15 +181,15 @@ You can choose between 3 different hero variants to use in `app/(site)/page.tsx`
151181

152182
#### Image optimization
153183

154-
Optimize images in seconds for free with ImageOptim. Install on your Mac, then open the `public` folder in Finder. Select all images, right-click, and choose "Open with > ImageOptim". This will optimize all images in the folder.
184+
I recommend optimizing images fast for free with [ImageOptim](https://imageoptim.com/mac). Install on your Mac, then open the `public` folder in Finder. Select all images, right-click, and choose "Open with > ImageOptim". This will optimize all images in the folder.
155185

156186
Note: DO NOT overdo it. You can easily make images look bad with lossy compression algorithms.
157187

158188
## Examples
159189

160-
- [https://davidlevai.com/](https://davidlevai.com/)
190+
- [https://davidlevai.com/](https://davidlevai.com/) - My own digital garden
191+
- [Dragons and Codes Digital Garden](https://dragonsandcodes.com) - Simple modifications [Source](https://github.com/dragonsandcodes/digital-garden-v2)
161192
- [Shafie Mukhre's Blog](https://shafiemukhre.com) - [Source](https://github.com/shafiemukhre/website-2023)
162-
- [Dragons and Codes Digital Garden](https://dragonsandcodes.com) - [Source](https://github.com/dragonsandcodes/digital-garden-v2)
163193

164194
**Create a PR and add your blog to this list if you're using the template!**
165195

@@ -182,7 +212,7 @@ Note: DO NOT overdo it. You can easily make images look bad with lossy compressi
182212
- [x] projects page
183213
- [x] about section on homepage
184214
- [x] search & command bar
185-
- [x] Analytics: Vercel, Umami
215+
- [x] Analytics: Vercel, Umami, Plausible
186216
- [x] Post series
187217
- [x] Not found page
188218
- [x] contributing docs
@@ -192,38 +222,46 @@ Note: DO NOT overdo it. You can easily make images look bad with lossy compressi
192222
- [x] Social sharing buttons
193223
- [x] Tags
194224
- [x] newsletter integration (form, api route, keys, thank you/welcome page, MailerLite provider)
225+
- [x] more MDX components (katex, math)
226+
- [x] author content definition
227+
- [x] SEO improvements
195228
- [ ] Other newsletter providers (Convertkit, Substack, Buttondown, Mailchimp, etc)
196-
- [ ] Other analytics providers (fathom, simplelytics, plausible, etc)
197-
- [ ] CLI and/or recipes
229+
- [ ] Other analytics providers (fathom, simplelytics, etc)
230+
- [ ] RTL Support
198231
- [ ] Post series page
199232
- [ ] prev/next post links
200-
- [ ] related posts
233+
- [ ] related/similar posts
234+
- [ ] Donate component & page
235+
- [ ] CLI and/or recipes
201236
- [ ] Newsletter previous issues page
202237
- [ ] Layouts/templates system
203238
- [ ] Notion data source
204239
- [ ] Sanity data source
205-
- [ ] hero title and subtitle text HTML support(?)
206240
- [ ] Design improvements (whitespace, layout, etc.)
207-
- [ ] error, and loading pages
241+
- [ ] lightbox for images
242+
- [ ] implement content security policies
208243
- [ ] Code preview component
209244
- [ ] Code highlight improvements (copy code, theme)
210-
- [ ] `manifest.json`
211245
- [ ] Rich project cards
246+
- [ ] Landing page/offer page/freebie page
212247
- [ ] CV template
213248
- [ ] Authenticated pages and/or hidden content (behind email address)
214249
- [ ] 100 lighthouse score
215250
- [ ] Command bar fuzzy search in content
216-
- [ ] Pagination
217-
- [ ] SEO improvements
218251
- [ ] Accessibility audit
252+
- [ ] more MDX components (oembed)
253+
- [ ] error, and loading pages
219254
- [ ] TypeScript fixes
255+
- [ ] Redesign social page (link in bio)
220256
- [ ] Redesign uses page
221257
- [ ] Redesign projects page
222258
- [ ] general refactor
223259
- [ ] general cleanup
224-
- [ ] implement content security policies
225260
- [ ] implement a videoask-like solution for the hero section
226261
- [ ] RSS feed improvements (image, description, etc.)
262+
- [ ] custom admin CMS(?)
263+
- [ ] hero title and subtitle text HTML support(?)
264+
- [ ] Pagination (?)
227265
- [ ] multi-author support (?)
228266
- [ ] Post like counter (?)
229267
- [ ] Visitor counter (?)

app/(site)/[slug]/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { notFound } from "next/navigation";
33
import { allPages } from "contentlayer/generated";
44
import { format, parseISO } from "date-fns";
55

6-
import { Mdx } from "@/components/mdx-components";
6+
import { Mdx } from "@/components/mdx";
77

88
interface PageProps {
99
params: {

app/(site)/layout.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import siteMetadata from "@/lib/metadata";
2+
import { cn } from "@/lib/utils";
13
import Footer from "@/components/footer";
24
import { Navigation } from "@/components/navigation";
35

@@ -17,7 +19,9 @@ export default function RootLayout({ children }: RootLayoutProps) {
1719
</a>
1820
<Navigation />
1921
<div className="order-last mt-[calc(theme(spacing.16)-theme(spacing.3))]"></div>
20-
<main id="main-content">{children}</main>
22+
<main className={cn("mt-20", siteMetadata.activeAnnouncement && "mt-32 pt-28 md:pt-0")} id="main-content">
23+
{children}
24+
</main>
2125
<Footer />
2226
<div
2327
className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"

app/(site)/page.tsx

+13-15
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
import Image from "next/image";
22
import Link from "next/link";
3-
import { notFound } from "next/navigation";
4-
import { allPages, allPosts } from "@/.contentlayer/generated";
5-
import { compareDesc } from "date-fns";
3+
import { allPages, allPosts } from "contentlayer/generated";
64
import { ArrowRight } from "lucide-react";
75

8-
import { defaultAuthor } from "@/lib/metadata";
9-
import { cn } from "@/lib/utils";
6+
import siteMetadata, { defaultAuthor } from "@/lib/metadata";
7+
import { sortByDate } from "@/lib/utils";
108
import { HeroImage } from "@/components/hero-image";
119
import { HeroMinimal } from "@/components/hero-minimal";
1210
import { HeroSimple } from "@/components/hero-simple";
1311
import { HeroVideo } from "@/components/hero-video";
1412
import { Sidebar } from "@/components/home-sidebar";
15-
import { Mdx } from "@/components/mdx-components";
13+
import { Mdx } from "@/components/mdx";
1614
import NewsletterSubscribe from "@/components/newsletter-subscribe";
1715
import PostPreview from "@/components/post-preview";
1816

@@ -30,10 +28,8 @@ export default async function Home() {
3028
const aboutPage = await getAboutPage();
3129
const posts = allPosts
3230
.filter((post) => post.status === "published")
33-
.sort((a, b) =>
34-
compareDesc(new Date(a.lastUpdatedDate || a.publishedDate), new Date(b.lastUpdatedDate || b.publishedDate))
35-
)
36-
.slice(0, 8);
31+
.sort(sortByDate)
32+
.slice(0, siteMetadata.postsOnHomePage);
3733

3834
return (
3935
<div className="pb-10">
@@ -61,12 +57,14 @@ export default async function Home() {
6157
</aside>
6258
</div>
6359
</div>
64-
<NewsletterSubscribe
65-
title="I also write deep dives in email"
66-
description="I write about coding, design, digital nomad life, and solopreneurship. Join over 1,000 other developers in
60+
{siteMetadata.newsletterUrl && (
61+
<NewsletterSubscribe
62+
title="I also write deep dives in email"
63+
description="I write about coding, design, digital nomad life, and solopreneurship. Join over 1,000 other developers in
6764
getting better in business. Unsubscribe whenever."
68-
buttonText="Send me the emails"
69-
/>
65+
buttonText="Send me the emails"
66+
/>
67+
)}
7068
{aboutPage && (
7169
<div className="container max-w-6xl">
7270
<h2 className="mb-8 font-heading text-4xl font-bold">Who&apos;s this girl again?</h2>

app/(site)/posts/[slug]/page.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { cn } from "@/lib/utils";
1111
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
1212
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
1313
import { Separator } from "@/components/ui/separator";
14-
import { Mdx } from "@/components/mdx-components";
14+
import { Mdx } from "@/components/mdx";
1515
import { PostSeriesBox } from "@/components/post-series-box";
1616
import { SocialShare } from "@/components/social-share";
1717
import { TableOfContents } from "@/components/table-of-contents";
@@ -59,6 +59,8 @@ export async function generateMetadata({ params }: PostProps): Promise<Metadata>
5959
return {
6060
title: post.title,
6161
description: post.description,
62+
authors: [{ name: post?.author?.name || defaultAuthor.name, url: defaultAuthor.website }],
63+
keywords: post.tags,
6264
};
6365
}
6466

app/(site)/posts/page.tsx

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Metadata } from "next";
2-
import { allPosts } from "@/.contentlayer/generated";
3-
import { compareDesc } from "date-fns";
2+
import { allPosts } from "contentlayer/generated";
43

54
import { defaultAuthor } from "@/lib/metadata";
5+
import { sortByDate } from "@/lib/utils";
66
import PostPreview from "@/components/post-preview";
77

88
export async function generateMetadata(): Promise<Metadata> {
@@ -13,11 +13,7 @@ export async function generateMetadata(): Promise<Metadata> {
1313
}
1414

1515
export default function Blog() {
16-
const posts = allPosts
17-
.filter((post) => post.status === "published")
18-
.sort((a, b) =>
19-
compareDesc(new Date(a.lastUpdatedDate || a.publishedDate), new Date(b.lastUpdatedDate || b.publishedDate))
20-
);
16+
const posts = allPosts.filter((post) => post.status === "published").sort(sortByDate);
2117

2218
return (
2319
<div className="container mb-4">

app/(site)/tags/[slug]/page.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Metadata } from "next";
22
import { notFound } from "next/navigation";
3-
import { allPosts, Post } from "@/.contentlayer/generated";
4-
import { compareDesc } from "date-fns";
3+
import { allPosts, Post } from "contentlayer/generated";
54

5+
import { sortByDate } from "@/lib/utils";
66
import PostPreview from "@/components/post-preview";
77

88
// Get sorted articles from the contentlayer
@@ -33,7 +33,7 @@ export default async function TagPage({ params }: { params: { slug: string } })
3333
const posts = allPosts
3434
.filter((post) => post.status === "published")
3535
.filter((post) => post.tags?.includes(tag))
36-
.sort((a, b) => compareDesc(new Date(a.publishedDate), new Date(b.publishedDate)));
36+
.sort(sortByDate);
3737

3838
if (!posts) {
3939
notFound();

app/(site)/tags/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Metadata } from "next";
22
import Link from "next/link";
33
import { notFound } from "next/navigation";
4-
import { allPosts } from "@/.contentlayer/generated";
4+
import { allPosts } from "contentlayer/generated";
55

66
import siteMetadata from "@/lib/metadata";
77
import { getTagsWithCount } from "@/lib/utils";

app/(social)/social/page.tsx

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Image from "next/image";
22
import { Mail } from "lucide-react";
33

4-
import { defaultAuthor } from "@/lib/metadata";
4+
import siteMetadata, { defaultAuthor } from "@/lib/metadata";
55
import { projects } from "@/lib/projects-data";
66
import { CopyButton } from "@/components/copy-button";
77
import NewsletterSubscribe from "@/components/newsletter-subscribe";
@@ -39,12 +39,14 @@ export default async function SocialPage() {
3939
<Signature />
4040
</div>
4141
</div>
42-
<NewsletterSubscribe
43-
title="I also write deep dives in email"
44-
description="I write about coding, design, digital nomad life, and solopreneurship. Join over 1,000 other developers in
42+
{siteMetadata.newsletterUrl && (
43+
<NewsletterSubscribe
44+
title="I also write deep dives in email"
45+
description="I write about coding, design, digital nomad life, and solopreneurship. Join over 1,000 other developers in
4546
getting better in business. Unsubscribe whenever."
46-
buttonText="Send me the emails"
47-
/>
47+
buttonText="Send me the emails"
48+
/>
49+
)}
4850
</>
4951
);
5052
}

app/feed.xml/route.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { allPosts } from "@/.contentlayer/generated";
1+
import { allPosts } from "contentlayer/generated";
22
import RSS from "rss";
33

44
import siteMetadata, { BASE_URL, defaultAuthor } from "@/lib/metadata";

0 commit comments

Comments
 (0)