- Published on
Over-engineering thvu.dev
- Authors
- Name
- Thang Huu Vu
- @thanghvu
Read on to learn how I bootstrapped this site from template starter to the current over-engineered state. I called it over-engineered because I think I over-killed the site by optimizing the Lighthouse score, CSP headers, and all the service integrations I squeeze in it 😅
Table of Contents
Get started
Template
I use @Tim's awesome starter template to bootstrap the project. The template is feature-rich, easy to customize, and easily the best starter for Next.js blogging out there.
Hosting
Hosted on Vercel, with domain from Google Domain.
Enhancements
Blogging
I enhance the current writing feature with mdx-embed. For me, it is always nice to have the ability to embed examples from CodePen. To have this I need to add CodePen to MDX components:
import { CodePen } from "mdx-embed";
const MDXComponents = {
// ... other components
CodePen,
};
And it is done! I also added a new feature, which is Real-time page view count using PlanetScale (More on this later in Guestbook section below)
Guestbook
This feature is inspired by Lee Robinson's guestbook and was fun to work with. I learned from him how to set up and use PlanetScale for serverless database (previously using redis with Upstash).
My tweak in the implementation is authentication for guest users. I used next-auth to integrate with Github, Google, and Line to provide authentication.
Authentication with next-auth
Install
yarn add next-auth
Configure providers
Create a [...nextauth].js file in pages/api/auth:
import NextAuth from "next-auth";
export default NextAuth({
providers: [
/* ...providers */
],
});
Be sure to check with the design guideline to implement the login buttons correctly. Details on how to integrate with each provider are also available on next-auth's documentation. Below is a summary for my providers:
| Providers | Why | Design guideline |
|---|---|---|
| Most common login OAuth is a must have | ||
| Github | For developers | Github |
| Line | My current employer 😎 | Line |
Custom Sign In page
To override the default /signin page, create a custom page and refer it in [...nextauth].js:
export default NextAuth({
// ... other configs
pages: {
signIn: "/auth/signin",
},
});
With Google Analytics
View a page
Check out the Next.js official example with-google-analytics. It covers almost everything you need to integrate GA into your Next.js app.
Get pageviews
I use this to display all views for my site.
I use this snippet to get pageviews. Notice that now Google is rolling out GAv4 that removed the View panel. Therefore, if you want the snippet to work, in your Google Console you need to create a Universal Analytic Property and use its ID:
- From your Analytics Admin, click on Create Property
- Enter the property name and click on Show advance options
- Enable Create a Universal Analytics property. Check both Create both a Google Analytics 4 and a Universal Analytics property and Enable enhanced measurement for Google Analytics 4 property
SSG with DatoCMS
Instead of using the /data directory for projects data, I decided to integrate with DatoCMS for some Jamstack vibes. The process is quite simple:
- Register a new account at DatoCMS
- Add DatoCMS integration in Vercel
- Fetch the GraphQL API in
getStaticProps
I found everything I need in the Next.js cms-datocms example and DatoCMS documentation. Working with DatoCMS graphql is a nice experience, as I have never worked with graphql before.
Tips with environment variables: Make use of the Vercel CLI. After added an integration, you can use
vercel env pullto get the ENV variables to your local.envfile. I found this to be pretty handy when integrating services.
🎧 Now Playing with Spotify
Another feature stolen from Lee 😄. See his article to learn how to set things up with Spotify API.
The Music Equalizer component is my touch, which is also available on CodePen as a CSS-only version. The visual is taken from Instagram story's music equalizer.
The end result ✨
Lighthouse score
The generated site already has a very high Lighthouse score. I added PWA and perfected the bars. Lighthouse report is available here.
What I improved compared to the starter project:
- PWA: Better icons, manifest
- SEO: Added robots.txt
PWA
The easiest way to implement PWA support in a Next.js project is to use next-pwa.
favicons
I use https://realfavicongenerator.net to generate the icons.
manifest.json
To get the perfect score for PWA, ensure the following in icons:
- A 512x512 image for splash screen
- An image with
purpose: any maskable. I use maskable.app to help with this.
Content Security Policy
Websites I use to get CSP rating:
If you are implementing CSP for your site, my suggestion is to start with super strict CSP (lockdown) and build from there.
Monitoring with Sentry
Sentry with Next.js is a delightful experience. The steps are:
- Go to https://sentry.io to register for a free tier account.
- Add Sentry integration to Vercel.
- Install the package and run the wizard:
yarn add @sentry/nextjs
npx @sentry/wizard -i nextjs
I only want Sentry in production. To do this, in my next.config.js:
module.exports = isDevelopment
? nextConfig
: withSentryConfig(nextConfig, SentryWebpackPluginOptions);
withSentryConfighas to be the farthest wrapper to ensure that your source maps include changes from all other Webpack plugins.
Conclusion
And there you have it, my over-engineered site, my sweet home on the internet. I learned a lot from other people while building this site. I hope you learned something from this post too. I will continue to upgrade this site in the future, hopefully with more original ideas. Stay tuned for future posts!
The source code of this site is available on Github.