-
-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f8b01bc
commit 338ea26
Showing
3 changed files
with
326 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,310 @@ | ||
--- | ||
title: 'One-stop Starter to Maximize Efficiency on Next.js & Tailwind CSS Projects' | ||
publishedAt: '2022-01-05' | ||
description: 'Increase your efficiency by using preconfigured starter repository, with rich development features and automations.' | ||
englishOnly: 'true' | ||
banner: 'sawyer-bengtson-umRPY9w3q1c-unsplash_aw4tur' | ||
tags: 'nextjs,tailwindcss,typescript' | ||
--- | ||
|
||
## Introduction | ||
|
||
I made the [ts-nextjs-tailwind-starter](https://github.com/theodorusclarence/ts-nextjs-tailwind-starter) after I got tired of setting up a new project and have to initialize Tailwind CSS every single time. After some months, this starter has grown and is filled with a lot of development automation and tools that help me when I'm developing. | ||
|
||
This is something that I use every project init, features are carefully curated, and put into this repository. | ||
|
||
## Features | ||
|
||
According to my list, these are all the features that I incorporate on ts-nextjs-tailwind-starter: | ||
|
||
- ⚡️ Next.js 12 | ||
- ⚛️ React 17 | ||
- ✨ TypeScript | ||
- 💨 Tailwind CSS 3 — Configured with CSS Variables to extend the **primary** color | ||
- 💎 Pre-built Components — Components that will **automatically adapt** with your brand color | ||
- 🃏 Jest — Configured for unit testing | ||
- 📈 Absolute Import and Path Alias — Import components using `@/` prefix | ||
- 📏 ESLint — Find and fix problems in your code, also will **auto-sort** your imports | ||
- 💖 Prettier — Format your code and **Tailwind CSS classes** consistently | ||
- 🐶 Husky & Lint Staged — Run scripts on your staged files before they are committed | ||
- 🤖 Conventional Commit Lint — Make sure you & your teammates follow the conventional commit | ||
- ⏰ Standard Version Changelog — Generate your changelog using `yarn release` | ||
- 👷 Github Actions — Lint your code on PR | ||
- 🚘 Automatic Branch and Issue Autolink — Branch will be automatically created on issue **assigned**, and auto-linked on PR | ||
- 🔥 Snippets — A collection of useful snippets | ||
- 👀 Default Open Graph — Awesome open graph generated using [og.thcl.dev](https://github.com/theodorusclarence/og), fork it, and deploy! | ||
- 🗺 Site Map — Automatically generate sitemap.xml | ||
- 📦 Expansion Pack — Easily install common libraries, additional components, and configs | ||
|
||
Quite a lot huh? I'm going to take an in-depth look at each feature and automation with this post. | ||
|
||
--- | ||
|
||
## Easy Initial Config | ||
|
||
Don't you hate it when you use a starter, then you see some branding or default configs left out unchanged? | ||
|
||
<CloudinaryImg | ||
mdx | ||
publicId='theodorusclarence/blogs/one-stop-starter/initial-config_oaxcgp' | ||
alt='initial-config' | ||
width={1405} | ||
height={993} | ||
/> | ||
|
||
I prepared a unique word that you can find, with some guide of what to override. You can remove the comments after you override them, and leave them if you haven't. Treat them as a to-do comment. | ||
|
||
## Pre-built Components | ||
|
||
I prepared a set of components that is neutral and can be used to help boost your speed in development. These are components that have a **high chance of being used**, not just getting deleted after you finished cloning the repository. | ||
|
||
<LiteYouTubeEmbed | ||
id='xawHHhqIVVo' | ||
poster='maxresdefault' | ||
title='Pre-built components demo' | ||
noCookie={true} | ||
/> | ||
|
||
All animations are configured to be **motion-safe**. | ||
|
||
### Don't like the theme? | ||
|
||
You can change it with CSS Variables. I prepared **all Tailwind CSS colors** converted to CSS Variables in the `styles/colors.css` file that you can copy and use. | ||
|
||
<CloudinaryImg | ||
mdx | ||
publicId='theodorusclarence/blogs/one-stop-starter/list-of-tailwind-classes_jqwdxa' | ||
alt='list-of-tailwind-classes' | ||
width={1504} | ||
height={824} | ||
/> | ||
|
||
See more details about components on the [demo page](https://tsnext-tw.thcl.dev/components) | ||
|
||
## SEO Enhancement | ||
|
||
Do you want your project to be indexed to search engines? Yeah, me too. I optimized the SEO by preparing a custom Seo component and adding [next-sitemap](https://www.npmjs.com/package/next-sitemap). | ||
|
||
<CloudinaryImg | ||
mdx | ||
publicId='theodorusclarence/blogs/one-stop-starter/seo-component_xpzsab' | ||
alt='seo-component' | ||
width={1501} | ||
height={921} | ||
/> | ||
|
||
If you want to use the default meta tag, just add `<Seo />` on top of your page. | ||
|
||
You can also customize it per page by overriding the title, description as props | ||
|
||
```tsx | ||
<Seo title='Next.js Tailwind Starter' description='your description' /> | ||
``` | ||
|
||
or if you want to still keep the site title like `%s | Next.js Tailwind Starter`, you can use `templateTitle` props. | ||
|
||
## Minimal Dependencies | ||
|
||
I tried to keep the dependencies small, not the devDeps tho, you'll see why after you see a bunch of automation I create. Here are the 3 dependencies (excluding Next.js and React deps) | ||
|
||
1. [clsx](https://bundlephobia.com/package/clsx@latest), a utility for constructing `className` strings conditionally. | ||
2. [react-icons](https://bundlephobia.com/package/react-icons@latest), easily import popular icon packs in SVG format. | ||
3. [tailwind-merge](https://github.com/dcastil/tailwind-merge), override tailwind CSS classes without using !important. | ||
|
||
The tailwind-merge can be used by importing `clsxm` from `@/lib/clsxm`. All of the pre-built components are using clsxm to ease the use of the reusable components. | ||
|
||
Here is a thread that I made about tailwind-merge: | ||
|
||
<TweetCard tweetId='1475685363003768836' /> | ||
|
||
## Absolute Import & Path Alias | ||
|
||
```tsx | ||
import Header from '../../../components/Header'; | ||
|
||
// simplified to | ||
|
||
import Header from '@/components/Header'; | ||
``` | ||
|
||
Reduce the complexity of importing components by using absolute import, and a nice path alias to differentiate **your** **code** and **external libraries.** | ||
|
||
## Prettier with Tailwind CSS Class Sorter | ||
|
||
In this repository, I set it up so it will automatically sort class based on the custom config file. It even works with clsx or classnames! You don't need to ask your colleague to download another VS Code extension. All of it is bound to the repository. | ||
|
||
<LiteYouTubeEmbed | ||
id='AJt5na1E7DE' | ||
poster='sddefault' | ||
title='Tailwind CSS Class Sort Demo' | ||
noCookie={true} | ||
/> | ||
|
||
## ESLint | ||
|
||
This repository is prepared with ESLint to reduce human errors during development. Don't worry there won't be any annoying **styling lint** because all of it is taken care of with Prettier. Some cool features such as: | ||
|
||
### Auto Import Sort & Unused Import Removal | ||
|
||
Don't you hate it when you have to revise your code because your reviewer told you to **reorder imports**? If they haven't automated it, do yourself a favor by recommending this starter. | ||
|
||
<LiteYouTubeEmbed | ||
id='6W6FSJ6mq6c' | ||
poster='sddefault' | ||
title='Auto Import Sort & Unused Import Removal Demo' | ||
noCookie={true} | ||
/> | ||
|
||
## Husky & Lint Staged | ||
|
||
There are 3 Husky hooks that will help you with the automation of: | ||
|
||
1. **pre-commit**, run **eslint check** with 0 tolerance to warnings and errors and **format the code** using prettier | ||
2. **commit-msg**, run commitlint to ensure the use of the [Conventional Commit](https://theodorusclarence.com/library/conventional-commit-readme) for commit messages | ||
3. **post-merge**, running `yarn` every `git pull` or after merging to ensure all new packages are installed and ready to go | ||
|
||
Oh right, you also don't have to wait that long because husky only the code that you **stage** (using [lint-staged](https://github.com/okonet/lint-staged)). | ||
|
||
What about the type check, or if the staged code made the other fail? Don't burden your efficiency, just chuck it into Github Actions to run in the background. | ||
|
||
## Github Actions | ||
|
||
I love automation and I put some useful workflows that you can use. | ||
|
||
### Type Check, Whole ESLint & Prettier | ||
|
||
For the sake of efficiency, we don't run whole project checks on your local machine. That takes too long just to commit simple changes. We will run it on Github Actions instead, then you can continue working while waiting for it to complete. | ||
|
||
Here are the complete lists that will be checked: | ||
|
||
1. **ESLint** - will fail if there are any warnings and errors | ||
2. **Type Check** - will fail on `tsc` error | ||
3. **Prettier Check** - will fail if there are any formatting errors | ||
4. **Test** - will fail if there are any test failures | ||
|
||
<CloudinaryImg | ||
mdx | ||
publicId='theodorusclarence/blogs/one-stop-starter/inline-lint_h8zjrn' | ||
alt='inline-lint' | ||
width={828} | ||
height={623} | ||
/> | ||
|
||
Github also provides useful inline warnings in the Files Changed tab on the PR. | ||
|
||
### Auto Create Branch | ||
|
||
We can automatically create a branch from the latest main branch after you **assign** an issue. | ||
|
||
<LiteYouTubeEmbed | ||
id='b2TWOdF2kW0' | ||
poster='maxresdefault' | ||
title='Auto create branch demo' | ||
noCookie={true} | ||
/> | ||
|
||
This will create a **consistent branch name** with the issue number in front of them, and some issue context. | ||
|
||
p.s. You have to install the app for your organization/account/repository from the [GitHub Marketplace](https://github.com/marketplace/create-issue-branch) for this to work | ||
|
||
## Auto Link PR to Issue | ||
|
||
We automated the branch creation, the lint & the test process on the PR, what's next? Yep, linking PR to issue. That is **super annoying** and I always **forgot** to do it. We'll automate it using our consistent branch name. | ||
|
||
<LiteYouTubeEmbed | ||
id='lOWtCVXq3os' | ||
poster='maxresdefault' | ||
title='Auto Link PR to Issue demo' | ||
noCookie={true} | ||
/> | ||
|
||
It also provides a nice description of related issues, so your reviewer can check the issue first before reviewing. | ||
|
||
## Open Graph Generator | ||
|
||
I also provided an open graph application that you can [fork and deploy to vercel](https://github.com/theodorusclarence/og) for **free**. It is automatically used with the SEO component and will generate a dynamic open graph based on the page title and description. | ||
|
||
It defaults to my deployment, but please **fork it** and self-host. Because I might change the API without notice and could break your app's opengraph. | ||
|
||
<CloudinaryImg | ||
mdx | ||
publicId='theodorusclarence/blogs/one-stop-starter/og-generate_kcbpzt' | ||
alt='og-generate' | ||
width={1191} | ||
height={884} | ||
/> | ||
|
||
You can play around with the API on [og.thcl.dev](https://og.thcl.dev/). You can even customize it with your own brand based on the repo! | ||
|
||
## Snippets | ||
|
||
Snippets are crucial if you want to make a consistent convention across the application. I prepared some snippets that can help you code faster and more effectively. | ||
|
||
<CloudinaryImg | ||
mdx | ||
publicId='theodorusclarence/blogs/one-stop-starter/snippets_i9vgeg' | ||
alt='snippets' | ||
width={887} | ||
height={907} | ||
/> | ||
|
||
See more detail on [this file](https://github.com/theodorusclarence/ts-nextjs-tailwind-starter/blob/main/.vscode/typescriptreact.code-snippets) | ||
|
||
### Regions | ||
|
||
You might notice the `#region` with green highlight comments. This is something that can be used with `reg` snippets. You can easily separate your logic into named regions, then fold them if they are insignificant. | ||
|
||
<CloudinaryImg | ||
mdx | ||
publicId='theodorusclarence/blogs/one-stop-starter/regions_ws4imm' | ||
alt='regions' | ||
width={1307} | ||
height={415} | ||
/> | ||
|
||
The lesser noise the better. You can also use `⌘K + ⌘8` to fold all regions. | ||
|
||
### Snippets Wrap | ||
|
||
This is something that I recently added because it is annoying to wrap a component with React Fragment or refactoring className with clsx. So I created a snippet pattern called **Snippets Wrap** that can help you with that. | ||
|
||
<LiteYouTubeEmbed | ||
id='baCi6IfJzvo' | ||
poster='sddefault' | ||
title='Snippets Wrap' | ||
noCookie={true} | ||
/> | ||
|
||
## Expansion Pack | ||
|
||
I have to keep this starter minimal, but there are some libraries that I often use in every project. So I created a bash script to **install, config, and add additional components** to this starter. | ||
|
||
Currently, there are some packs in the [expansion-pack repository](https://github.com/theodorusclarence/expansion-pack) | ||
|
||
- React Hook Form + Form Input Components | ||
- [Storybook](https://theodorusclarence.com/blog/nextjs-storybook-tailwind) | ||
- Cypress + workflow to run on Vercel preview on push | ||
- [Toast with React Query / SWR](https://theodorusclarence.com/blog/react-loading-state-pattern) | ||
- [Dialog Manager with Zustand](https://github.com/theodorusclarence/dialog-manager) | ||
- NProgress | ||
|
||
Here is a demo for the React Hook Form one | ||
|
||
<LiteYouTubeEmbed | ||
id='fna-ekaU0A4' | ||
poster='sddefault' | ||
title='Expansion pack demo' | ||
noCookie={true} | ||
/> | ||
|
||
Hit the terminal then grab some coffee. You're back with complete components also a **sandbox** page to see how to implement the library. | ||
|
||
For more demo, check out the [repository readme](https://github.com/theodorusclarence/expansion-pack) | ||
|
||
## Star the repository | ||
|
||
Liking the features? This repository basically grows with me, so the features will go through changes and improvement. If you got anything in mind, leave a comment below, or [open a discussion](https://github.com/theodorusclarence/ts-nextjs-tailwind-starter/discussions). | ||
|
||
Finally, I would be **thrilled** if you give a **star** to the repository. | ||
|
||
[https://github.com/theodorusclarence/ts-nextjs-tailwind-starter](https://github.com/theodorusclarence/ts-nextjs-tailwind-starter) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters