Skip to content

Commit e481e58

Browse files
committed
feat: built the MVP
1 parent e7b508a commit e481e58

Some content is hidden

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

98 files changed

+10891
-4470
lines changed

.env.example

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#Next
2+
NEXT_PUBLIC_BASE_URL=https://localhost:3000

.eslintrc.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"extends": "next/core-web-vitals"
2+
"extends": ["next/core-web-vitals", "prettier"]
33
}

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ yarn-error.log*
3333
# typescript
3434
*.tsbuildinfo
3535
next-env.d.ts
36+
.contentlayer

.prettierignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
dist
2+
node_modules
3+
.next
4+
build
5+
.contentlayer

.prettierrc.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/** @typedef {import("@ianvs/prettier-plugin-sort-imports").PluginConfig} SortImportsConfig*/
2+
/** @typedef {import("prettier").Config} PrettierConfig*/
3+
/** @typedef {{ tailwindConfig: string }} TailwindConfig*/
4+
5+
/** @type { PrettierConfig | SortImportsConfig | TailwindConfig } */
6+
const config = {
7+
arrowParens: "always",
8+
printWidth: 120,
9+
singleQuote: false,
10+
jsxSingleQuote: false,
11+
semi: true,
12+
trailingComma: "es5",
13+
tabWidth: 2,
14+
plugins: ["@ianvs/prettier-plugin-sort-imports", "prettier-plugin-tailwindcss"],
15+
importOrder: [
16+
"^(react/(.*)$)|^(react$)",
17+
"^(next/(.*)$)|^(next$)",
18+
"<BUILTIN_MODULES>",
19+
"<THIRD_PARTY_MODULES>",
20+
"",
21+
"^types$",
22+
"^@/env(.*)$",
23+
"^@/types/(.*)$",
24+
"^@/config/(.*)$",
25+
"^@/lib/(.*)$",
26+
"^@/hooks/(.*)$",
27+
"^@/components/ui/(.*)$",
28+
"^@/components/(.*)$",
29+
"^@/styles/(.*)$",
30+
"^@/app/(.*)$",
31+
"",
32+
"^[./]",
33+
],
34+
importOrderParserPlugins: ["typescript", "jsx", "decorators-legacy"],
35+
};
36+
37+
module.exports = config;

CHANGELOG.md

Whitespace-only changes.

CONTRIBUTING.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Contributing Guidelines
2+
3+
I'd love your input! This project is from developers for developers. Please feel free to:
4+
5+
- Report a bug
6+
- Discuss the current state and ideas for improvements
7+
- Submit a fix
8+
- Propose new features
9+
10+
## How?
11+
12+
Based on [Github Flow](https://guides.github.com/introduction/flow/index.html).
13+
14+
1. Fork the repo and create your branch from `develop`.
15+
2. Add your code.
16+
3. Update the documentation.
17+
4. Make sure your code lints.
18+
5. Open pull request to `develop` branch.
19+
20+
## Any contributions you make will be under the MIT Software License
21+
22+
In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project.

LICENSE

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

README.md

+142-20
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,156 @@
1-
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
1+
# Modern Developer Digital Garden Starter
2+
3+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/thedevdavid/digital-garden)
4+
5+
An open source 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.
6+
7+
This project is from developers for developers. Please feel free to report a bug, discuss the current state, submit ideas for improvements, submit a fix, propose new features, or whatever you want. All contributions are welcome! Read more at the [contributing guidelines](./CONTRIBUTING.md).
8+
9+
If you love this template and/or use it, please give it a star on GitHub. This will help more people discover it, thus help improving the template.
10+
11+
[![GitHub stars](https://img.shields.io/github/stars/thedevdavid/digital-garden?style=social)](
12+
13+
**Note: This project is always evolving and it's far from being perfect or even done.** I'm always open to suggestions and contributions. Feel free to open an issue or a PR if you have any ideas or suggestions. You can also see the [roadmap](#features--roadmap) for planned features if you want to contribute.
14+
15+
## Table of Contents
16+
17+
- [Motivation](#motivation)
18+
- [Getting Started](#getting-started)
19+
- [Writing content](#writing-content)
20+
- [Deployment](#deployment)
21+
- [Customization](#customization)
22+
- [Fonts](#fonts)
23+
- [Colors](#colors)
24+
- [Metadata](#metadata)
25+
- [Analytics](#analytics)
26+
- [Newsletter subscription](#newsletter-subscription)
27+
- [Hero section](#hero-section)
28+
- [Other tips & tricks](#other-tips--tricks)
29+
- [Image optimization](#image-optimization)
30+
- [Examples](#examples)
31+
- [Features & Roadmap](#features--roadmap)
32+
33+
## Motivation
34+
35+
As a developer who creates content, I want to have a digital garden where I can share my thoughts and ideas with the world. Now, there's not really a "perfect solution" for this currently. With included analytics, SEO, email subscribtions, modern tooling, simple design, etc. We either have to build one from scratch, use a design template and code the features, or use a CMS/no-code tool.
36+
37+
So I decided to build a solution that I would use myself. This is the result.
238

339
## Getting Started
440

5-
First, run the development server:
41+
1. Use the repo as a template
42+
2. Install dependencies with `pnpm install`
43+
3. Edit `utils/metadata.ts` with your information
44+
4. Edit `utils/usesData.ts` with your information
45+
5. Edit `utils/projectsData.ts` with your information
46+
6. Edit `content/pages/now` with your information
47+
7. Edit `content/pages/about` with your information
48+
8. Run the development server with `pnpm dev`
49+
50+
Open [http://localhost:3000](http://localhost:3000) in your browser to see the result.
51+
52+
### Writing content
53+
54+
You can write content in Markdown or MDX. The content is located in `content/` and is organized in folders. The `pages` folder contains the pages. The `posts` folder contains the blogposts. The `projects` folder contains the projects.
55+
56+
### Deployment
57+
58+
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. Don't forget to update `package.json` author information.
59+
60+
## Customization
61+
62+
### Fonts
63+
64+
This project uses [Inter](https://rsms.me/inter/) as the default font. You can change it on `app/layout.tsx` using the `next/fonts` package.
65+
66+
### Colors
67+
68+
The project uses Tailwind colors and @shadcn/ui config. Customize the colors on `globals.css`.
69+
70+
### Metadata
71+
72+
You can change the metadata in `utils/metadata.ts`. This will be used around the site for social links, handles, SEO, and OG.
73+
74+
### Analytics
75+
76+
_WIP_ as I'm still deciding which analytics tools to support. Feel free to open an issue if you have any suggestions or a PR if you want to implement it yourself.
77+
78+
### Newsletter subscription
79+
80+
_WIP_ as I'm still deciding which email tools to support. Feel free to open an issue if you have any suggestions or a PR if you want to implement it yourself.
81+
82+
### Hero section
83+
84+
You can choose between 3 different hero variants to use in `app/(site)/layout.tsx`.
85+
86+
1. `Simple` - A simple centered hero section with image, title, socials, and subtitle.
87+
2. `Video` - 2 column hero section with Videoask embed on one side and title and subtitle on the other.
88+
3. `Image` - 2 column hero section with image on one side and title, socials, and subtitle on the other.
89+
90+
### Other tips & tricks
691

7-
```bash
8-
npm run dev
9-
# or
10-
yarn dev
11-
# or
12-
pnpm dev
13-
```
92+
#### Image optimization
1493

15-
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
94+
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.
1695

17-
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
96+
## Examples
1897

19-
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
98+
- [https://davidlevai.com/](https://davidlevai.com/)
2099

21-
## Learn More
100+
Create a PR and add your digital garden to this list if you're using the template!
22101

23-
To learn more about Next.js, take a look at the following resources:
102+
## Features & Roadmap
24103

25-
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26-
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
104+
- [x] Basic functionality of reading pages and posts
105+
- [x] Basic design dark/light mode
106+
- [x] MDX code highlighting
107+
- [x] Readme.md
108+
- [x] `robots.txt` & `sitemap.xml`
109+
- [x] RSS Feed
110+
- [x] Reading time estimate
111+
- [x] LICENSE
112+
- [x] contributing.md
113+
- [x] MDX components (TOC & footnotes)
114+
- [x] general config & metadata (author, URL, socials, etc.)
115+
- [x] uses page
116+
- [x] Link in bio page
117+
- [x] OG image generation
118+
- [x] projects page
119+
- [x] about section on homepage
120+
- [ ] Design improvements (whitespace, layout, etc.)
121+
- [ ] `manifest.json`
122+
- [ ] search & command bar
123+
- [ ] newsletter integration
124+
- [ ] Post series
125+
- [ ] Hidden content (behind email subscription)
126+
- [ ] 100 lighthouse score
127+
- [ ] Command bar fuzzy search in content
128+
- [ ] Pagination
129+
- [ ] SEO improvements
130+
- [ ] analytics (fathom, simplelytics, vercel)
131+
- [ ] Accessibility audit
132+
- [ ] TypeScript fixes
133+
- [ ] Redesign uses page
134+
- [ ] Redesign projects page
135+
- [ ] general refactor
136+
- [ ] general cleanup
137+
- [ ] implement content security policies
138+
- [ ] implement a videoask-like solution for the hero section
139+
- [ ] Post like counter (?)
140+
- [ ] Visitor counter (?)
141+
- [ ] code playground instead of code highlighting (?)
142+
- [ ] Categories and/or tags (?)
143+
- [ ] Commenting system (?)
144+
- [ ] Social sharing buttons (?)
145+
- [ ] keyboard-based navigation with hotkeys (?)
146+
- [ ] multiple layouts (sidebar, full-width, etc.) (?)
147+
- [ ] multilang support (?)
27148

28-
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
149+
## Inspiration & Mentions
29150

30-
## Deploy on Vercel
151+
- [Delba Oliveira Personal Blog](https://github.com/delbaoliveira/website) - Using and structuring table of contents with Contentlayer
152+
- [timlrx/tailwind-nextjs-starter-blog](https://github.com/timlrx/tailwind-nextjs-starter-blog) - Idea
31153

32-
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
154+
## Support
33155

34-
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
156+
If you love this template and/or use it, please give it a star on GitHub.

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

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { Metadata } from "next";
2+
import { notFound } from "next/navigation";
3+
import { allPages } from "contentlayer/generated";
4+
import { format, parseISO } from "date-fns";
5+
6+
import { Mdx } from "@/components/mdx-components";
7+
8+
interface PageProps {
9+
params: {
10+
slug: string;
11+
};
12+
}
13+
14+
async function getPageFromParams(params: PageProps["params"]) {
15+
const page = allPages.find((page) => page.slug === params.slug);
16+
17+
if (!page) {
18+
null;
19+
}
20+
21+
return page;
22+
}
23+
24+
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
25+
const page = await getPageFromParams(params);
26+
27+
if (!page) {
28+
return {};
29+
}
30+
31+
return {
32+
title: page.title,
33+
description: page.description,
34+
};
35+
}
36+
37+
export async function generateStaticParams(): Promise<PageProps["params"][]> {
38+
return allPages.map((page) => ({
39+
slug: page.slug,
40+
}));
41+
}
42+
43+
export default async function PagePage({ params }: PageProps) {
44+
const page = await getPageFromParams(params);
45+
46+
if (!page || (process.env.NODE_ENV === "development" && page.status !== "published")) {
47+
notFound();
48+
}
49+
50+
return (
51+
<div className="container max-w-6xl pb-10">
52+
<article className="prose mx-auto max-w-5xl dark:prose-invert prose-headings:mb-3 prose-headings:mt-8 prose-headings:font-heading prose-headings:font-bold prose-headings:leading-tight hover:prose-a:text-muted-foreground prose-a:prose-headings:no-underline">
53+
<h1 className="mt-0">{page.title}</h1>
54+
{page.description && <p className="m-0 text-xl">{page.description}</p>}
55+
{page.lastUpdatedDate && (
56+
<time className="text-sm text-slate-500">
57+
Last updated: {format(parseISO(page.lastUpdatedDate), "LLLL d, yyyy")}
58+
</time>
59+
)}
60+
<hr className="my-4" />
61+
<Mdx code={page.body.code} />
62+
</article>
63+
</div>
64+
);
65+
}

app/(site)/error.tsx

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"use client";
2+
3+
import { useEffect } from "react";
4+
5+
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
6+
useEffect(() => {
7+
console.error(error);
8+
}, [error]);
9+
10+
return (
11+
<div className="items-center justify-center text-center">
12+
<h2 className="font-heading">Something went wrong!</h2>
13+
<button onClick={() => reset()}>Try again</button>
14+
</div>
15+
);
16+
}

0 commit comments

Comments
 (0)