-
Notifications
You must be signed in to change notification settings - Fork 49
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
feat(web): get Env from API endpoint #678
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: a84d3d6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
5 Skipped Deployments
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #678 +/- ##
==========================================
+ Coverage 87.79% 88.50% +0.71%
==========================================
Files 158 160 +2
Lines 10871 10919 +48
Branches 1164 1201 +37
==========================================
+ Hits 9544 9664 +120
+ Misses 1327 1255 -72 ☔ View full report in Codecov by Sentry. |
📦 Next.js Bundle Analysis for @blobscan/webThis analysis was generated by the Next.js Bundle Analysis action. 🤖
|
Page | Size (compressed) |
---|---|
global |
318.58 KB (🔴 +72.96 KB) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script>
tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
New Pages Added
The following pages were added to the bundle from the code in this PR:
Page | Size (compressed) | First Load | % of Budget (350 KB ) |
---|---|---|---|
/block_neighbor |
251 B |
318.83 KB | 91.09% |
/stats |
348.26 KB |
666.84 KB | 190.53% |
Eight Pages Changed Size
The following pages changed size from the code in this PR compared to its base branch:
Page | Size (compressed) | First Load | % of Budget (350 KB ) |
---|---|---|---|
/ |
355.55 KB |
674.13 KB | 192.61% (🟢 -3.94%) |
/address/[address] |
30.17 KB |
348.75 KB | 99.64% (🟢 -3.87%) |
/blob/[hash] |
30.51 KB |
349.09 KB | 99.74% (🟢 -3.41%) |
/blobs |
81.5 KB |
400.08 KB | 114.31% (🟡 +13.91%) |
/block/[id] |
15.65 KB |
334.23 KB | 95.49% (🟢 -3.77%) |
/blocks |
78.65 KB |
397.23 KB | 113.49% (🟡 +13.74%) |
/tx/[hash] |
18.85 KB |
337.43 KB | 96.41% (🟡 +1.60%) |
/txs |
78.05 KB |
396.63 KB | 113.32% (🟡 +11.70%) |
Details
Only the gzipped size is provided here based on an expert tip.
First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link
is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.
Any third party scripts you have added directly to your app using the <script>
tag are not accounted for in this analysis
The "Budget %" column shows what percentage of your performance budget the First Load total takes up. For example, if your budget was 100kb, and a given page's first load size was 10kb, it would be 10% of your budget. You can also see how much this has increased or decreased compared to the base branch of your PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this. If you see "+/- <0.01%" it means that there was a change in bundle size, but it is a trivial enough amount that it can be ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good.
I left some comments with some changes we should do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a suggested change we could follow in order to export a client env vars schema that we can use later to enforce typing in the exposed env
object in the Env
provider
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";
// See booleanSchema from packages/zod/src/schemas.ts
// We need to redefine it because we can't import ts files from here
const booleanSchema = z
.string()
.refine((s) => s === "true" || s === "false")
.transform((s) => s === "true");
const networkSchema = z.enum([
"mainnet",
"holesky",
"sepolia",
"gnosis",
"chiado",
"devnet",
]);
const clientEnvVars = {
PUBLIC_BEACON_BASE_URL: z.string().url().default("https://beaconcha.in/"),
PUBLIC_BLOBSCAN_RELEASE: z.string().optional(),
PUBLIC_EXPLORER_BASE_URL: z.string().url().default("https://etherscan.io/"),
PUBLIC_NETWORK_NAME: networkSchema.default("mainnet"),
PUBLIC_SENTRY_DSN_WEB: z.string().url().optional(),
PUBLIC_POSTHOG_ID: z.string().optional(),
PUBLIC_POSTHOG_HOST: z.string().default("https://us.i.posthog.com"),
PUBLIC_SUPPORTED_NETWORKS: z
.string()
.default(
'[{"label":"Ethereum Mainnet","href":"https://blobscan.com/"},{"label":"Gnosis","href":"https://gnosis.blobscan.com/"},{"label":"Holesky Testnet","href":"https://holesky.blobscan.com/"},{"label":"Sepolia Testnet","href":"https://sepolia.blobscan.com/"}]'
),
PUBLIC_VERCEL_ANALYTICS_ENABLED: booleanSchema.default("false"),
PUBLIC_VERCEL_GIT_COMMIT_SHA: z.string().optional(),
};
export const clientEnvVarsSchema = z.object(clientEnvVars);
export const env = createEnv({
/**
* Specify your server-side environment variables schema here. This way you can ensure the app isn't
* built with invalid env vars.
*/
server: {
DATABASE_URL: z.string().url(),
FEEDBACK_WEBHOOK_URL: z.string().optional(),
NODE_ENV: z.enum(["development", "test", "production"]),
METRICS_ENABLED: booleanSchema.default("false"),
TRACES_ENABLED: booleanSchema.default("false"),
...clientEnvVars,
},
/**
* Destructure all variables from `process.env` to make sure they aren't tree-shaken away.
*/
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
FEEDBACK_WEBHOOK_URL: process.env.FEEDBACK_WEBHOOK_URL,
METRICS_ENABLED: process.env.METRICS_ENABLED,
NODE_ENV: process.env.NODE_ENV,
TRACES_ENABLED: process.env.TRACES_ENABLED,
PUBLIC_BEACON_BASE_URL: process.env.PUBLIC_BEACON_BASE_URL,
PUBLIC_BLOBSCAN_RELEASE: process.env.PUBLIC_BLOBSCAN_RELEASE,
PUBLIC_EXPLORER_BASE_URL: process.env.PUBLIC_EXPLORER_BASE_URL,
PUBLIC_NETWORK_NAME: process.env.PUBLIC_NETWORK_NAME,
PUBLIC_SENTRY_DSN_WEB: process.env.PUBLIC_SENTRY_DSN_WEB,
PUBLIC_POSTHOG_ID: process.env.PUBLIC_POSTHOG_ID,
PUBLIC_POSTHOG_HOST: process.env.PUBLIC_POSTHOG_HOST,
PUBLIC_SUPPORTED_NETWORKS: process.env.PUBLIC_SUPPORTED_NETWORKS,
PUBLIC_VERCEL_ANALYTICS_ENABLED:
process.env.PUBLIC_VERCEL_ANALYTICS_ENABLED,
PUBLIC_VERCEL_GIT_COMMIT_SHA: process.env.PUBLIC_VERCEL_GIT_COMMIT_SHA,
},
skipValidation: !!process.env.CI || !!process.env.SKIP_ENV_VALIDATION,
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would import the clientEnvVarsSchema in the Env
provider to parse the returned json coming from the api
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
One more thing: don't forget to update the docs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some more comments.
/** | ||
* Specify your client-side environment variables schema here. | ||
* For them to be exposed to the client, prefix them with `NEXT_PUBLIC_`. | ||
*/ | ||
client: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should avoid redeclaring all the env vars in the client
field again, which is what we're trying to avoid by exposing them from the server.
Upon further inspection, I realise that there're some of them we should keep defined at build time. Those are:
NEXT_PUBLIC_BLOBSCAN_RELEASE
: This one we actually set it when building the docker image.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA
: This is a default variable that Vercel uses so we can't remove the prefix
@@ -26,34 +44,11 @@ export const env = createEnv({ | |||
DATABASE_URL: z.string().url(), | |||
FEEDBACK_WEBHOOK_URL: z.string().optional(), | |||
NODE_ENV: z.enum(["development", "test", "production"]), | |||
METRICS_ENABLED: booleanSchema.default("false"), | |||
TRACES_ENABLED: booleanSchema.default("false"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are the env vars we want to expose now from the server:
PUBLIC_BEACON_BASE_URL
PUBLIC_EXPLORER_BASE_URL
PUBLIC_NETWORK_NAME
PUBLIC_POSTHOG_HOST
PUBLIC_POSTHOG_ID
PUBLIC_SENTRY_DSN_WEB
PUBLIC_SUPPORTED_NETWORKS
We remove the prefix NEXT_
to prevent nextjs from injecting them during build time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, remember to update the docs with the new renamed env vars and any reference to them (i.e. deploy_vercel_env.sh
, turbo.json
, etc)
METRICS_ENABLED: z.boolean().default(false), | ||
TRACES_ENABLED: z.boolean().default(false), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rollback to booleanSchema
here
It's necessary because the true
or false
values are set as string and we need to parse them to their boolean counterparts
@@ -0,0 +1,33 @@ | |||
import type { NextApiRequest, NextApiResponse } from "next"; | |||
|
|||
import { env } from "@blobscan/env"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should send the env vars located in the env.mjs
file
Also, let's remove the @blobscan/env
package from the package.json
as those are not used in the web app
|
||
switch (method) { | ||
case "GET": { | ||
const parsedEnv = clientEnvVarsSchema.safeParse(env); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need to parse this again as env
object is already typified.
|
||
const clientEnv = Object.fromEntries( | ||
Object.entries(parsedEnv.data) | ||
.filter(([key]) => key.startsWith("NEXT_")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we apply the change mentioned above about removing the NEXT_
prefix we should update this to filter en vars starting with PUBLIC_
instead
Checklist
Description
The environment variables on the client side are now obtained from an
api
endpoint when the app initializes. This way, you should be able to change their values without redeploying for future deployment changes.Related Issue (Optional)
Closes #87