Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prerenderd HTML dosen't get invalidated #48

Closed
christophebeling opened this issue Feb 3, 2021 · 9 comments · Fixed by #125
Closed

Prerenderd HTML dosen't get invalidated #48

christophebeling opened this issue Feb 3, 2021 · 9 comments · Fixed by #125
Assignees
Labels
bug Something isn't working
Milestone

Comments

@christophebeling
Copy link
Contributor

After deployment pretended HTML doesn't get invalidated. I checked the invalidation in CloudFront, only assets (/Icons, /fonts) get invalidated.

@ofhouse
Copy link
Member

ofhouse commented Feb 3, 2021

Thanks for reporting, I will try to reproduce this behaviour with some of our examples later today.
Assets served from the prefix _next/static/* should not be part of any invalidation.

@ofhouse ofhouse added the bug Something isn't working label Feb 3, 2021
@christophebeling
Copy link
Contributor Author

Bildschirmfoto 2021-02-03 um 14 07 32

@ofhouse
Copy link
Member

ofhouse commented Feb 3, 2021

Thanks for sharing!
The invalidations seem intentional here because these are assets uploaded from the public/folder I guess.
While it is a valid use case to serve assets from the public folder, I recommend importing assets from the code, so that Next.js can optimize (append a hash to the filename) them for usage together with a CDN.

// Icon.js
import noEntryIcon from './assets/icons8-no-entry.svg`

export default function MyIconComponent() {
  return <img src={noEntryIcon} />
}

Doing it this way, Next.js will output the asset as something like _next/static/.../icons8-no-entry.2fdhad82.svg which is an immutable route thanks to the unique hash 2fdhad82 appended to the filename.
So when the file changes, Next.js will append a new hash, which also produces a new route on the CDN.


However what is bad here, is that we don't check if the content of the file has actually changed when doing a deployment.
So when I have a file public/favicon.ico and I don't change the file between two deployments I would expect that no invalidation is issued for this file.


Looking at the screenshot, the only actual route that gets invalidated is /404.
Are the other routes served by Lambdas (SSR) is that the bug you are describing here?

@christophebeling
Copy link
Contributor Author

Thanks for your detailed reply. The point with the assets is fair. We definitely gonna change that. However, the problem that we're facing is that the pre-rendered Html doesn't get invalidated, which results in no changes apply on our website until I manually trigger an invalidation for all directories in CloudFront.

@christophebeling
Copy link
Contributor Author

I've just been having a brief look into your code. In the create-invalidation.js you limit the paths to 15 per invalidation and then invalidate in batches. Unfortunately, for me, there is always just one invalidation happening. Could this be a possible issue?

@ofhouse
Copy link
Member

ofhouse commented Feb 4, 2021

Yes, that's my assumption what is happening here 👍

I also left a todo in the code, because we never actually checked a case with more than 15 invalidations.
https://github.com/dealmore/terraform-aws-next-js/blob/ad7047c94fa5025e448056361de8fa5cd65b42f4/packages/deploy-trigger/src/create-invalidation.ts#L9

@ofhouse ofhouse self-assigned this Feb 4, 2021
@christophebeling
Copy link
Contributor Author

Ok. So, just to clarify (I'm new to next-js), is it considered best practice to load all assets from the code via webpack? I played around with a few libraries, tried next-images which seems to work but didn't find any for fonts. Also, will this be working with nextjs 10 image objects?

@ofhouse
Copy link
Member

ofhouse commented Feb 4, 2021

As for all in software it depends 😄
Loading assets via webpack is recommended for assets that you know your application needs at build time, Things like icons, css-background-images or webfonts fall into this category.
Importing them is not limited to JavaScript code. For example you can also load webfonts directly from your CSS:

@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 500;
    src: local(''),
      url('./fonts/montserrat-v15-latin-500.woff2') format('woff2')
}

I think you don't need any additional configuration, since loading assets is already built-in in Next.js (and the underlaying webpack configuration). The important thing here is to use relative paths (./fonts/montserrat-v15-latin-500.woff2) instead of absolute paths (/fonts/montserrat-v15-latin-500.woff2) so that webpack can check for the referenced files on your local filesystem at build time.

@christophebeling
Copy link
Contributor Author

Well, for sure it always "depends", however, when you're using a framework it is usually opinionated and there are best practices. The next.js documentation explicitly advises to put build time assets in the public folder:
https://nextjs.org/docs/basic-features/static-file-serving
As far as I read it from the documentation the next-jst10 next/image component also relies on images are stored in the public folder, however, I might be wrong here, I'm not a frontend dev.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants