1

I need to render images on my statically built Next.js website and I would like to do it according to today's best practices.

I have seen that Next.js includes next/Image which takes care of most optimisation out of the box. Given I won't have images saved in multiple sizes, I was looking at imgix to do this for me.

How I envisioned this setup is, I dump all images in an S3 bucket (I only know the filename) which will be used by imgix. Given the filename and a width requirement, I would then leave it to next/Image to resize and render the images via its imgix loader.

Where I get confused is, the Next.js docs mention both the width and height should be known prior. How would I know the height if I only provide the width to imgix and let it do its resize magic?

I am sure I am missing something obvious here, but a pointer would be highly appreciated.

linkyndy
  • 17,038
  • 20
  • 114
  • 194
  • 1
    Unfortunately, since next/image relies on real-time image manipulation, it does not support static exports and only supports SSR Next.js apps out the box. Check out - https://github.com/cyrilwanner/next-optimized-images – Sean W Feb 01 '22 at 03:27
  • I'm converting to terraform and ran across this - if you use AWS this looks to be a great solution for static sites - https://github.com/milliHQ/terraform-aws-next-js-image-optimization/tree/main/examples/with-next-js-export – Sean W Feb 02 '22 at 02:04

3 Answers3

4

A little disclaimer, I work at imgix.

Hopefully I can clarify by outlining the responsibilities of some things you mentioned:

  • Next.js is responsible for text/html/dom manipulation/more (i.e. placing img tags with the appropriate attributes in markup/html/etc.)

  • imgix is responsible for all the image processing (i.e. pretty much as you described, s3 => request a specific size => done)

  • devs/designers are responsible for page layout (e.g. css, overall html structure)

The linked section in the Next.js docs does a good job explaining layout shift and how to avoid it (it may or may not be an issue for you).

The height (and width) of your images are determined by your page’s layout. For example, you’ve designed an image gallery that displays uniformly sized images (i.e. each image is bounded above by the top of the row, below by the bottom of the row, and left/right by the columns).

How would I know the height if I only provide the width to imgix and let it do its resize magic?

One way of knowing what the dimensions of your images are/should be is for your designer to tell you what they should be. Many of us aren't that lucky so if you are the designer, once you’re satisfied with your layout you can inspect the width/height of the rendered images and then use that information to provide width/height attributes to the Next.js component.

They also specify a third option which involves using "layout="fill" which causes the image to expand to fill its parent element." If you do go with this third option remember "When using layout='fill', the parent element must have position: relative."

Again, this is all within the context of avoiding layout shift. If you specify the width of images to imgix the height will be calculated according to the aspect ratio of the original image. You can also specify aspect ratio along with other parameters to get the desired effect.

eric
  • 1,029
  • 1
  • 8
  • 9
  • 1
    Thank you, Eric, for your detailed answer. I think it's worth mentioning that my images will be displayed one on top of the other, similarly to a social media feed, where the width is known and the height is dictated by the resize based on the aspect ratio. Given this, I cannot find a general height rule to specify in Next.js, because of the dynamic height. – linkyndy Jan 15 '22 at 12:17
  • 1
    If you know the width and the aspect ratio, you can multiply the two to determine the height. i.e. ```const width=500; ``` – Sean W Feb 01 '22 at 03:24
  • I don't know this prior to rendering the image; I guess this is also part of the reason I am using an image optimiser. – linkyndy Feb 01 '22 at 21:29
0

As far as I've read in the documentation here and know from my projects, Next.js already does this using sharp internally, thus always serves the correctly sized image for each device while using next/image component. Without the need to have the image in different sizes.

Relevant section from the documentation

Some of the optimizations built into the Image component include:

  1. Improved Performance: Always serve correctly sized image for each device, using modern image formats.

  2. Visual Stability: Prevent Cumulative Layout Shift automatically.

  3. Faster Page Loads: Images are only loaded when they enter the viewport, with optional blur-up placeholders

  4. Asset Flexibility: On-demand image resizing, even for images stored on remote servers

Fabio Nettis
  • 1,150
  • 6
  • 18
  • Below that, they state the bits around having to specify the width and height, which is exactly the concern I had in my question. – linkyndy Feb 01 '22 at 21:34
  • Well the one thing you would know is the height since that just depends on the display size, for the width you can programmatically calculate the parents width if you want to stretch the image. – Fabio Nettis Feb 02 '22 at 12:26
  • I feel the point of my question is being missed. I mentioned "I only provide the width", while the height isn't something I can calculate, given I know nothing more at this stage about the image. – linkyndy Feb 02 '22 at 18:02
0

I ended up uploading to imgix at build time, which would also return me the image's dimensions. Based on those I calculated the ratio, and based on that and the desired width, I could compute the height as well.

linkyndy
  • 17,038
  • 20
  • 114
  • 194