Published on

Image Upload Guide

Authors
  • avatar
    Name
    Jaehyeok, Yu
    Twitter

Introduction

The tailwind starter blog has out of the box support for Next.js's built-in image component and automatically swaps out default image tags in markdown or mdx documents to use the Image component provided.

Usage

For a markdown file, the default image tag can be used and the default img tag gets replaced by the Image component in the build process.

Assuming we have a file called sample_image.jpg in data/img/sample_image.jpg, the following line of code would generate the optimized image.

![sample_image](/static/images/blog/sample_image.jpeg)
sample_image

Alternatively, since we are using mdx, we can just use the image component directly! Note, that you would have to provide a fixed width and height. The img tag method parses the dimension automatically.

<Image alt="sample_image" src="/static/images/blog/sample_image.jpeg" width={128} height={256} />

Note: If you try to save the image, it is in webp format, if your browser supports it!

sample_image

Benefits

  • Smaller image size with Webp (~30% smaller than jpeg)
  • Responsive images - the correct image size is served based on the user's viewport
  • Lazy loading - images load as they are scrolled to the viewport
  • Avoids Cumulative Layout Shift
  • Optimization on demand instead of build-time - no increase in build time!

Limitations

  • Due to the reliance on next/image, unless you are using an external image CDN like Cloudinary or Imgix, it is practically required to use Vercel for hosting. This is because the component acts like a serverless function that calls a highly optimized image CDN.

    If you do not want to be tied to Vercel, you can remove imgToJsx in remarkPlugins in lib/mdx.js. This would avoid substituting the default img tag.

    Alternatively, one could wait for image optimization at build time to be supported. A different library, next-optimized-images does that, although it requires transforming the images through webpack which is not done here.

  • Images from external links are not passed through next/image

  • All images have to be stored in the public folder e.g /static/images/sample_image.jpeg

Image Sorted (gallery)

Features images served using next/image component. The locally stored images are located in a folder with the following path: /static/images/[your folder]/[filename].jpg

Since we are using mdx, we can create a simple responsive flexbox grid to display our images with a few tailwind css classes.

<div className="-mx-2 flex flex-wrap overflow-hidden xl:-mx-2">
  <div className="my-1 w-full overflow-hidden px-2 xl:my-1 xl:w-1/2 xl:px-2">
    <img src="/static/images/blog/yujaehyeok/landscapes_1.jpeg" alt="sample1" className="w-full h-40 object-cover" />
  </div>
  <div className="my-1 w-full overflow-hidden px-2 xl:my-1 xl:w-1/2 xl:px-2">
    <img src="/static/images/blog/yujaehyeok/landscapes_2.jpeg" alt="sample2" className="w-full h-40 object-cover" />
  </div>
  <div className="my-1 w-full overflow-hidden px-2 xl:my-1 xl:w-1/2 xl:px-2">
    <img src="/static/images/blog/yujaehyeok/landscapes_3.jpeg" alt="sample3" className="w-full h-40 object-cover" />
  </div>
  <div className="my-1 w-full overflow-hidden px-2 xl:my-1 xl:w-1/2 xl:px-2">
    <img src="/static/images/blog/yujaehyeok/landscapes_4.jpeg" alt="sample4" className="w-full h-40 object-cover" />
  </div>
</div>
sample1
sample2
sample3
sample4

With MDX v2, one can interleave markdown in jsx as shown in the example code.