- 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 pull
to get the ENV variables to your local.env
file. 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);
withSentryConfig
has 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.