I'm using Webpack with StaticSite. My environment...
# help
t
I'm using Webpack with StaticSite. My environment variables seem to go missing when building... Works fine in development.
Copy code
const site = new StaticSite(this, "website", {
      path: "stack/website",
      buildOutput: "dist",
      buildCommand: "yarn build",
      customDomain,
      environment: {
        API_ENDPOINT: api.url,
      },
      // ...
    });
From package.json:
Copy code
"scripts": {
    "start": "sst-env -- webpack serve --open",
    "build": "webpack build"
  }
Any help or insight is welcomed.
f
Hey @Tim V, yeah as @Artemiy Davydov mentioned below, can CRA removes any environment variable not prefixed with
REACT_APP
.
Can you rename
API_ENDPOINT
to
REACT_APP_API_ENDPOINT
both in ur construct and in ur React app, and then give it a try again?
t
yessir. trying now.
Though, I'm not baking a react app... does that matter?
f
oh hmm.. what build framework r u using? Vite?
t
What's weirder is that my environment variable value is "{{ API_ENDPOINT }}" when I console.log from my webpack config.
Nunjucks, here.
Again... it works in development, but the prod build loses it.
so doing the whole ... sst start ... in the stack root and then going into the website folder and running ... sst-env -- webpack serve .. works perfectly.
f
u mean if you do
console.log
in ur frontend code, u can see
{{ API_ENDPOINT }}
in the console tab?
t
In my Webpack.config.js.
f
does that printed out at build time?
ie. it’s printing out
{{ API_ENDPOINT }}
in ur terminal when u build right?
t
when I run "sst-build", the value isn't the api.url, it is the string literal "{{ API_ENDPOINT }}" somehow.
Feels like the token isn't resolving.
But I really don't know.
f
that’s fine..
{{ API_ENDPOINT }}
gets replaced at deploy time. Here’s how it works https://docs.serverless-stack.com/frontend#how-passing-environment-variables-works
t
For background...
I worked through the getting started tutorial. I understood the process.env.API_ENDPOINT replacement in the front-end javascript code, specifically, and I've also gotten the environment variables to work for my lambdas (api gateway and cf listeners).
That was a few months ago... Oct/Nov of last year.
If I do...
Copy code
const site = new StaticSite(this, "website", {
      path: "stack/website",
      buildOutput: "dist",
      buildCommand: "FOO=BAR yarn webpack build",
      customDomain,
      environment: {
        API_ENDPOINT: api.url,
      },
I can see FOO in the process.env at build time, but not the API_ENDPOINT.
works fine with "$ sst start" and "$ sst-env -- webpack serve".
f
Yeah yeah,
sst start
and
sst deploy
work differently.
If you look at the link above, on
sst deploy
the value for
api.url
is not available at build time.
SST builds the app with placeholders.
ie.
Copy code
$ API_ENDPOINT="{{ API_ENDPOINT }}" FOO=BAR yarn webpack build
After the
Api
construct is deployed, SST will replace all occurrences of
{{ API_ENDPOINT }}
with the real value.
We should document this better in the dos
After you
sst deploy
, what’s value do you see for
process.env.API_ENDPOINT
?
t
Does that get replaced in front-end JS files, only?
f
And HTML files
t
ok
so, last night ...
f
Can i see how
API_ENDPOINT
is used in ur frontend?
t
I was hacking away...
Copy code
<script type="module">
    window.API_ENDPOINT = "{{ API_ENDPOINT }}";
</script>
and
(that first one was an HTML file.)
Copy code
import Cookies from "./Cookies";

try {
    console.log("FOOBAR", process.env.API_ENDPOINT);
} catch(e) {}

const API = {};
API.invoke = (path, body) => {
    const headers = new Headers();
    const AccessToken = Cookies.get("AccessToken");
    if (AccessToken) headers.set("Authorization", AccessToken);
    return fetch(`${window.API_ENDPOINT}/${path}`, { method: "POST", headers, body: JSON.stringify(body) })
        .then(response => response.json());
};
export default API;
That's in a JS file.
f
I see. Is the Site public? I want to take a look at the deployed html and js?
t
I'm deploying now.
(re-deploying)
f
yup 👍
t
Going to DM you.
Sent you links.
f
Got it!
What’s the name of the html file in ur site?
t
index.html
I have a cloudfront viewer request listener in front of it normalize urls, removing "index.html".... just in case you try to access it directly.
f
is it
auth/index.html
or
index.html
at the root?
t
auth/index.html
f
ah i see.
t
You can get at it using /auth/
f
StaticSite
currently only replaces
{{ API_ENDPOINT }}
in root
index.html
.
t
The viewer request listener will serve the index.html at that folder.
f
It was designed with single page app in mind. But i think we should replace it in all HTML pages.
Let me push out a fix for this.
t
OMG really?
Possible ETA?
f
I can do today for sure. Do u need it before a certain time? I can try to make it.
t
That would be great.
f
With that fix, this should get replaced
Copy code
<script type="module">
    window.API_ENDPOINT = "{{ API_ENDPOINT }}";
</script>
So
window.API_ENDPOINT
should give u the deployed URL
t
well, all of that is me hacking around to get it in there.
If I know that process.env.API_ENDPOINT will get replaced in all HTML & JS files, that's all I need.
But still...
What happens...
Are the StaticSite files built with tokens and then SST does a find/replace on the built assets?
f
I’m not sure about
process.env.API_ENDPOINT
..
I’m looking at ur raw js file
process.env.API_ENDPOINT
is not being resolved by the build
As in, when you run this
Copy code
$ API_ENDPOINT="{{ API_ENDPOINT }}" FOO=BAR yarn webpack build
Does
process.env.API_ENDPOINT
not get resolved to
{{ API_ENDPOINT }}
?
t
I'm so wrapped around the axle... I feel like I've tried every combination I can think of.
f
Can you give this a try:
Copy code
$ API_ENDPOINT="{{ API_ENDPOINT }}" yarn webpack build
And look at ur JS file in the
dist
folder, do u see
process.env.API_ENDPOINT
or do u see
"{{ API_ENDPOINT }}"
?
t
Sure. So, I am adding this to one of my JS files...
Copy code
try {
    console.log("FOOBAR", process.env.API_ENDPOINT);
} catch(e) {}
And where did you want me to try
Copy code
$ API_ENDPOINT="{{ API_ENDPOINT }}" yarn webpack build
?
...into the buildCommand in StaticSite?
f
just manually in ur terminal
In ur website folder
t
oh
yes
I tried something similar
and I did get the expected result.
(I did $ FOO=BAR yarn webpack build.)
f
I mean if you run
Copy code
$ API_ENDPOINT="{{ API_ENDPOINT }}" yarn webpack build
and then look at the output JS file in
dist
, do you see
Copy code
try {
    console.log("FOOBAR", process.env.API_ENDPOINT);
} catch(e) {}
or
Copy code
try {
    console.log("FOOBAR", "{{ API_ENDPOINT }}");
} catch(e) {}
t
I can safely say that...
When webpack builds the files, the value of proess.env.API_ENDPOINT is "{{ API_ENDPOINT }}".
This is injected into my templates.
f
Just to verify, running
Copy code
$ API_ENDPOINT="{{ API_ENDPOINT }}" yarn webpack build
produces
Copy code
try {
    console.log("FOOBAR", "{{ API_ENDPOINT }}");
} catch(e) {}
right?
t
yessir
f
Can u do a grep the
dist
folder and see if there is any occurrence of
process.env.API_ENDPOINT
not being replaced with
"{{ API_ENDPOINT }}"
?
t
I can see the string literal "{{ API_ENDPOINT }}" is injected into the files that get written to ./dist
I cannot. There will be no results.
I am using Webpack to execute a Nunjucks build.
So, long story short, and to reset the issue...
f
Hmm.. something doesn’t add up here.. the JS file u sent me, it had
process.env.API_ENDPOINT
in there. Do you know why that’s happening?
t
I had it in there to try things.
I'm using Webpack to run a nunjucks compiler.
So, in the webpack.config.js, I have...
Copy code
const templateParameters = {};
templateParameters.API_ENDPOINT = process.env.API_ENDPOINT;
And I inject that into my nunjucks templates.
in the above, the value is "{{ API_ENDPOINT }}".
f
I see.. if the value is
{{ API_ENDPOINT }}
in the JS file, that should get replaced with the deployed url.
t
My compiled HTML files (the output from Nunjucks), there is a string literal left behind.
f
Yeah, HTML files not getting replaced, that I can fix.
t
To short circuit out all the nonsense... the point is... if {{ API_ENDPOINT }} is in an HTML or JS, that should be being replaced, yeah?
f
Currently,
{{ API_ENDPOINT }}
gets replaced in
index.html
and in ALL js files.
t
ok
I just put this in a JS file...
Copy code
console.log("{{ API_ENDPOINT }}");
And I'm re-deploying to see.
f
Yup yup
t
I don't -have- to use process.env.API_ENDPOINT in the HTMLs or JSs, right?
I just looked in the root HTML file... the value is updated, there! ...Sooooooo... if you make it update all HTML/JS in ./dist (and subfolders), that will do the trick.
f
Yeah, you don’t. I was going to suggest that, in this
Auth
page, instead of setting
module.API_ENDPOINT
in the html file. Can you try using
process.env.API_ENDPOINT
directly in JS?
I think that should work for you.
t
I think my problem really just revolves around having non-root-index files where the values are not being interpolated or replaced.
If I adjust to use process.env.API_ENDPOINT in the root-index files, it very well might work. It looks like it DID do just that in the root-index-html file already. I just didn't look there because I was fixated on the "/auth" folder which is the first thing a non-auth user sees... and I couldn't log in because the API endpoint wasn't correct. 🙂
Oroborus and all.
f
@Tim V I just cut a beta release with the fix
0.70.0-next.5
Can you give it a try and let me know if it works for you?
t
yessir
Need me to up @serverless-stack/resources as well?
f
yeah both cli and resources
which version r u on right now?
t
I was at 51
Need to update to aws-cdk-lib... gimme a minute
f
Ah 👍
t
Looks like it worked.
f
Nice. I will keep u posted when the release is out tonite.
t
Can't thank you enough.
Thank you.
f
Glad we finally figured it out 🎉
@Tim V released this in v0.69.1
t
Thank you. 🙂 🙂 🙂 @Frank
Hi @Frank. Would v0.69.2 have removed the process to replace tokens in -all- html files?
I removed and redeployed and now it seems to be working again. Got me...!
f
Hey @Tim V, this is released in
0.69.3
t
Thanks again. Not sure what my issue was, but all is well, now!