hey <@U01JVDKASAC> (I think this is probably your ...
# sst
d
hey @Frank (I think this is probably your domain, correct me if wrong), I am considering a construct to handle Next.JS Static exports, but handling the routing logic in Cloudfront for dynamic routes (
[id].tsx
). • Have you thought about this? • Do you think there is value and would SST have interest in such a thing? On the face of it, it would allow a simple, cheap entrypoint to Next.JS with capabilities more or less on par with something like CRA and Next.JS defaults and static exporting (not a SPA, but real static site). It would be devoid of features listed here.
An issue asking for something like this: Dynamic routing with next export to static · Issue #2542 · vercel/next.js (github.com)
f
hey @Derek Kershner, yeah that makes sense. Can this construct be built on top of
StaticSite
?
d
I will definitely look into using what currently exists in SST as much as possible, including trying to integrate your ideas regarding seamless deployments by intelligently separating html and static js.
f
Haha, the standard Next.js build does that automatically. Not sure if static export does something similar.
d
they are in separate folders, but I meant deploying them in separate behaviors and only updating the html one.
the new and old js would still be around
f
Yup yup
d
alright, just wanted to check with you before I researched, don’t wanna drop something on you guys that you would hate to support. Thanks, @Frank.
f
Yeah, once you get it to work, it’s likely we first put it out as an example first. And if more ppl ask for this, we will create an SST construct out of it, perhaps named
NextjsStaticSite
or
NextjsExportStaticSite
lol to make it less confusing with the existing construct.
d
let’s say IF I get it to work, lol.
i have not seen anyone be successful at this, in my preliminary research.
Hey @Frank, I am through the preliminary step, and actually am more pleased so far than I thought I would be… I am liking the StaticSite construct as a whole, definitely saving me time. To do dynamic route rewriting, I need access to a build file (
routes-manifest.json
), and I need to get a value from it up into the CDK. This doesn’t seem too bad to do from inside
StaticSite
, but there is really no way to grab after build, but before deploy. Or I could do it outside, but then I would have to build twice. Guidance?
Alright, @Frank, I have a fully working prototype for both dynamic and static paths, I just need your help getting
routes-manifest.json
into the CDK. I have tried a few methods, but am running into issues ranging from NPM not existing to not being able to run anything prior to
super
. Aside from re-creating
StaticSite
entirely, I am not sure where to go, but I bet you do.
Have it working with double builds, not ideal.
f
Hey @Derek Kershner, is it that you need to read from
routes-manifest.json
in order to configure the CloudFront distribution accordingly? I wonder if
Lazy
helps in this case:
Copy code
const site;

site = new StaticSite(this, "Site", {
  path: "path/to/src",
  buildOutput: "dist",
  buildCommand: "npm run build",
  cfDistribution: Lazy.any({
    produce(context) {
      const file = fs.readFileSync("path/to/routes-manifest.json");
      return {
        defaultBehavior: { ... },
        additionalBehaviors: { ... },
      };
    }
  }),
});
So inside
Lazy.any
, if you reference
site.s3Bucket
, then
produce
will get called after
site.s3Bucket
is created. At this point, the site has been built and
routes-manifest.json
should exist.
d
That totally worked. I am working out one more edge case, then I should be fully functional.
Alrighty, @Frank, I think it is ready for a PR if you want. This is not a good candidate for an example, in my estimation, due to the fact that it has a rather lengthy and ugly (due to both limitations and size constraints) custom cloudfront function inside it that would need to somehow be present. As such, I have a class
NextjsStaticSite
that extends
StaticSite
. For now I will just publish within my org, but let me know how you would like to proceed.
I also wonder about the
fileOptions
you use in
ReactStaticSite
and
ViteStaticSite
and what they mean?
Copy code
fileOptions: [
                {
                    exclude: "*",
                    include: "*.html",
                    cacheControl: "max-age=0,no-cache,no-store,must-revalidate",
                },
                {
                    exclude: "*",
                    include: ["*.js", "*.css"],
                    cacheControl: "max-age=31536000,public,immutable",
                },
            ]
The code as is, so you can decide.