twopluszero / next-images

Import images in Next.js (supports jpg, jpeg, svg, png and gif images)
MIT License
948 stars 67 forks source link

Dynamic asset prefix inside static pages #65

Closed megazazik closed 3 years ago

megazazik commented 3 years ago

This PR adds support of dynamicAssetPrefix in statically generated pages. See details here https://github.com/twopluszero/next-images/issues/63#issuecomment-762531376

arefaslani commented 3 years ago

@megazazik Could you just convert tabs to spaces? I didn't touch that because else it'll show my name in git blame, but you did the job :)

megazazik commented 3 years ago

@arefaslani I thought I removed all tabs in the second commit. Are you sure there are tabs in the file still? I don't see them.

arefaslani commented 3 years ago

@megazazik Ah sorry you're right. I was checking previous commit.

arefaslani commented 3 years ago

@megazazik This is my configuration file:

const withImages = require('next-images')
module.exports = withImages({
  esModule: true,
  assetPrefix: process.env.PUBLIC_URL,
  dynamicAssetPrefix: true,
  webpack(config, options) {
    return config
  }
})

I added this line in my hosts file to mimic CDN behavior:

cdn.example.com 127.0.0.1

I built the project using this command:

PUBLIC_URL=http://cdn.example.com:5000 yarn build

Then I started the project with this way and everything was fine:

yarn start -p 5000

But if I change the PUBLIC_URL variable to http://cdn2.example.com:5000 using this command:

PUBLIC_URL=http://cdn2.example.com:5000 yarn start -p 5000

It still shows the previous URL in chrome devtools. The URL that I used in build time. is this the expected behavior? Because I thought that you need to be able to change the asset prefix after build. Am I right?

peter-jozsa commented 3 years ago

Is your page statically generated where you checked it? If it is then did you enabled static page revalidation?

export async function getStaticProps() {
  return {
    props: {},
    revalidate: 1,
  }
}

If you enabled it then after several refreshes your static pages will be re-generated with the new asset prefix values.

If you are only using it in server-side rendered pages then asset prefix should be changed immediately when you start up the server and fire your first request.

arefaslani commented 3 years ago

@peter-jozsa I neither used getStaticProps nor getServerSideProps. Should I use one of these functions to make it work?

peter-jozsa commented 3 years ago

As far as I know statically generated pages are generated during next build which means the value of assetPrefix during build time will be statically generated into the HTMLs. If you change it during runtime by PUBLIC_URL=http://cdn2.example.com:5000 yarn start -p 5000 in your case it will do nothing since value of assetPrefix was already evaluated during build time and its value is persisted in the static HTML. But if you enable revalidation by returning { revalidate: 1 } in your getStaticProps function of the page you are telling next.js to regenerate that given page at most once in 1 sec. During page regenration the same will happen like when you run next build so the current runtime value of assetPrefix will be generated into the HTML code of the static page and in the end the you should see requests targeting cdn2.example.com:5000 after a few refreshes.