Skip to content

markplewis/sandi-plewis-blog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sandi Plewis' blog

This repository contains a Next.js application that serves as the front-end for www.sandiplewis.com.

A separate Sanity-powered CMS provides content for this application to consume, via the Sanity API.

This project uses:

  • Vercel for continuous integration and delivery (CI/CD)
  • Mailgun for email delivery
  • MongoDB for user authentication

At the time of this writing, this project was using:

VSCode plugins

You'll want to install the following VSCode plugins:

Installation

Duplicate the .env.local.example file and rename it to .env.local. Then, copy and paste the listed environment variables, tokens, IDs and secrets from your Vercel project dashboard. See .env.local.example for more information.

Once the environment variables are ready, run the following command to install the project dependencies:

# Install project dependencies
npm install

# Install Husky pre-push Git hook (see `.husky/pre-push`)
npm run prepare

MongoDB Compass

Optionally install the MongoDB Compass desktop application.

Startup

You can fire up the development server via:

npm run dev

The application will run at http://localhost:3000.

Production builds

Whenever a Vercel build is initiated, Vercel runs npm run build, which creates an optimized production build of the application (see the script comments in package.json for more information). This generates a .next directory, which Vercel then deploys to the production server.

If you run npm run build locally, you'll see the statically-built HTML files, etc. in the .next/server/pages/ directory.

See the Next.js CLI documentation.

Application details

Preview mode

This app uses next-sanity to provide a live, real-time preview experience for authenticatd users. Here's how it works:

  1. Navigating to /login will redirect you to the Sanity Studio login page where you can manage all of the documents that the Next.js application consumes.
  2. Navigating to /admin (in a sepatate browser tab) will bring you to an Auth.js-powered login form (a.k.a. next-auth).
  3. Upon form submission, the application will check whether the submitted email address belongs to an existing user in the MongoDB database (see pages/api/auth/[...nextauth].js). If so, then an email containing a "magic link" will be sent to that address.
  4. Clicking the "magic link" will redirect you back to the website, where you'll be logged in (your session will be stored in the MongoDB database).
  5. You'll then be immediately redirected to /api/preview where, via an authentication token, next-sanity will setup the listeners, etc. that are required in order to start streaming the Sanity dataset to the browser.
  6. You'll then be redirected back to the home page and a "preview mode" banner will appear at the top of the page until you log out by pressing the "Sign out" button (which logs you out of your Auth.js session then makes a request to /api/exit-preview to terminate preview mode).

Variables in CSS media queries

Unfortunately, it isn't possible to use CSS custom properties in media queries, like this:

@media (min-width: var(--bp-768)) {
  /* styles */
}

However, it may eventually be possible to use CSS environment variables in media queries, like this:

@media (min-width: env(--bp-768)) {
  /* styles */
}

Because environment variables don’t depend on the value of anything drawn from a particular element, they can be used in places where there is no obvious element to draw from, such as in @media rules, where the var() function would not be valid.

For a while, it was possible to polyfill this functionality via PostCSS, using postcss-env-function, however, it was removed from postcss-preset-env in version 8. See:

So, this project now uses postcss-design-tokens to achieve the same thing. It isn't quite as nice but it works (see: styles/design-tokens.json and styles/design-tokens.js). Here's an example:

@design-tokens url("../design-tokens.json") format("style-dictionary3");

@media (min-width: token("breakpoints.w768" to rem)) {
  /* styles */
}

Image aspect ratios

  • Novel and short story covers: 9:14 (portrait)
  • Author headshots: 1:1 (square)
  • Blog post hero images: 5:2 or 3:2 (depending on the breakpoint)
  • Blog post body photos: 3:2 (landscape) or 3:4 (portrait)

TODO