selected highlights

Nov 2021

dynamic imports

Exports don’t mix

named exports

export  { Component }

default exports

export default Component

Exports don’t mix

named exports

default exports

const DynamicComponent = dynamic(() => import('../components/hello'))
const DynamicComponent = dynamic(() =>
  import('@components/hello').then((mod) => mod.Hello)
)

Image src

static import

path string

import Image from 'next/image'
import profilePic from '../public/me.png'

const Home = () => <Image src={profilePic} />
import Image from 'next/image'

const Home = () => (
  <Image
    src="https://path.com/image.png"
    width={500}
    height={500}
  />
)

⚠️

Image Allow-list

module.exports = {
  images: {
    domains: ['example.com', 'example2.com'],
  },
}

Performance

<Image
  src="/me.png"
  alt="Picture of the author"
  width={500}
  height={500}
  priority
/>

add the priority property to the image that will be the Largest Contentful Paint (LCP) element for each page

No image size?

layout="fill"

adjust sizes with CSS

normalize images

when you own the service

modify API calls

when source has an image service

layout modes

intrinsic

scales down to fit container width
*up to image size

fixed

exactly set sizes

responsive

scales to fit container width

fill

scales to fit container width and height

configuration options

module.exports = {
  // ...
  images: {
    // default sizes
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
    // defaults image sizes
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
    // options: "default", "imgix", "cloudinary", "akamai", "custom"
    loader: 'default', 
    // configuration path to your loader
    path: '', 
    domains: ['https://bla.com'],
    // allow import images
    disableStaticImages: false, 
    // default minimum cache time in seconds
    minimumCacheTTL: 60 
  }
}

Types of routes

beforeInteractive

before page is interactive

afterInteractive

load immediately after interactive

lazyOnload

load when page is idle

Multi-Zones

+ i18n
+ External Directory imports

compile-time scripts

sitemap

TypeScript

JavaScript

v14 +

experimental modules

Types of routes

static routes

dynamic routes

Algorithm

get static routes

get dynamic routes

⚠️

define:
priority and change frequency

create XML

write to /public

Convetions

/pages

page components

/pages/api

serverless functions

/public

static assets

JSON

XML

type sitemapEntry = {
  path: string
  changefreq: string
  priority: number
 }
<url>
  <loc>https://domain.com</loc>
  <changefreq>monthly</changefreq>
  <priority>1</priority>
 </url>

more Edge Functions

i18n default domain

module.exports = {
  i18n: {
    locales: ['default', 'en', 'de', 'fr'],
    defaultLocale: 'default',
    localeDetection: false,
  },
  trailingSlash: true,
}

i18n default domain

import { NextRequest, NextResponse } from 'next/server'

const PUBLIC_FILE = /\.(.*)$/

export function middleware(request: NextRequest) {
  const shouldHandleLocale =
    !PUBLIC_FILE.test(request.nextUrl.pathname) &&
    !request.nextUrl.pathname.includes('/api/') &&
    request.nextUrl.locale === 'default'

  return shouldHandleLocale
    ? NextResponse.redirect(`/en${request.nextUrl.href}`)
    : undefined
}

more examples

What’s Next?

Usage feedback

Black Belt [Day 6]

By Atila

Black Belt [Day 6]

  • 508