Environment Variables are working on every component inside /pages but not in my Context component, in Nextjs. I’m wondering would Nextjs need some configuration?
(Note: Shopcontext.tsx is using a class component, that I got from a tutorial and I’m not familiar enough with context api to change it to a functional component. I tried.)
/* Below Shopcontext.tsx */
import React, { Component } from "react";
import Client from "shopify-buy";
const ShopContext = React.createContext({});
const client = Client.buildClient({
domain: "benson-bracelets.myshopify.com",
storefrontAccessToken: process.env.SHOPIFY_ACCESS_TOKEN as string,
});
interface State {
product: {};
products: Array<any>;
checkout: any;
}
export class ShopProvider extends Component {
state: State = {
product: {},
products: [],
checkout: {},
};
componentDidMount() {
if (localStorage.checkout_id) {
this.fetchCheckout(localStorage.checkout_id);
} else {
this.createCheckout();
}
}
/**
* Local storage will hold the checkoutid.
* Shopify will handle the check eachtime a checkout is started.
* @memberOf ShopProvider
*/
createCheckout = async () => {
const checkout = await client.checkout.create();
localStorage.setItem("checkout_id", checkout.id as any);
this.setState({ checkout: checkout });
};
fetchCheckout = (checkoutId: any) => {
client.checkout
.fetch(checkoutId)
.then((checkout) => {
this.setState({ checkout: checkout });
})
.catch((err) => {
console.log("Error Message, in ShopContext fetchCheckout: ", err);
});
};
fetchAllProducts = async () => {
await client.product.fetchAll().then((products) => {
this.setState({ products });
});
};
render() {
return (
<ShopContext.Provider
value={{
...this.state,
fetchAllProducts: this.fetchAllProducts,
fetchCheckout: this.fetchCheckout,
}}
>
{this.props.children}
</ShopContext.Provider>
);
}
}
const ShopConsumer = ShopContext.Consumer;
export { ShopConsumer, ShopContext };
export default ShopProvider;
/* .env file below */
SHOPIFY_DOMAIN=MY_DOMAIN_WOULD_BE_HERE
SHOPIFY_ACCESS_TOKEN=MY_API_WOULD_BE_HERE
/* _app.tsx below */
import React from "react";
import { AppProps } from "next/app";
import { ThemeProvider } from "@material-ui/core/styles";
import Theme from "../src/ui/Theme";
import { AnimatePresence } from "framer-motion";
import ShopContext from "../src/context/ShopContext";
import { wrapper } from "../src/store/store";
function MyApp(props: AppProps) {
const { Component, pageProps } = props;
return (
<React.Fragment>
<ThemeProvider theme={Theme}>
<ShopContext>
<AnimatePresence exitBeforeEnter>
<Component
{...pageProps}
{...props}
/>
</AnimatePresence>
</ShopContext>
</ThemeProvider>
</React.Fragment>
);
}
export default wrapper.withRedux(MyApp);
2
Answers
You should define your environment variable inside the
next.config.js
at the route of your project then you will get the env variable in every componentit is clearly mentioned in the nextjs document that
Trying to destructure process.env variables won't work due to the nature of webpack
For more detail please visit the below link
https://nextjs.org/docs/api-reference/next.config.js/environment-variables
I would like to add on to @Mohammad Shaban’s answer.
Ever since NextJS 9.4 there is support for loading environment variables through .env.local file .
By default all environment variables loaded through .env.local are only available in the Node.js environment, meaning they won’t be exposed to the browser.
In order to expose a variable to the browser you have to prefix the variable with NEXT_PUBLIC_. For example:
So don’t forget to prefix the env variables with NEXT_PUBLIC_ in case you are using them in browser.
For more information you can check this link