Deploying Environment Variables to Vercel with nextjs - reactjs

I am new to next.js and experiencing issues while trying to deploy environment variables to Vercel.
We are trying to deploy Stripe Payment Gateway to Vercel
Downloaded the Stripe Payment Gateway Sample code from
https://github.com/tmarek-stripe/demo-react-stripe-js
This is a nextjs application with a .env file that has a public and secret key pair.
Everything works fine while running on localhost , also the projects work fine on Vercel when I include the .env file in the git repository
As soon as I include the .env file in gitignore and push the updates to the repository , the .env file would not be shown and I get 500 Server error while trying to make test payments
Error while making payments
Below is the code for payment intent.js
import Stripe from "stripe";
const stripe = new Stripe(process.env.SECRET_KEY);
export default async (req, res) => {
if (req.method === "POST") {
try {
const { amount } = req.body;
const paymentIntent = await stripe.paymentIntents.create({
amount,
currency: "usd"
});
res.status(200).send(paymentIntent.client_secret);
} catch (err) {
res.status(500).json({ statusCode: 500, message: err.message });
}
} else {
res.setHeader("Allow", "POST");
res.status(405).end("Method Not Allowed");
}
};
The .Env File looks like below
PUBLISHABLE_KEY=pk_test_key
SECRET_KEY=sk_test_Secret Key
Read all the available articles online with no luck.
No changes were made to the code apart from Public and Secret Key in .env file
Please let me know how to hide the Environment Variables(as it contains the secret key) and at the same time use it in the production environment
Any help would be appreciated
Thanks in Advance

You can go to vercel.com, log-in to your account, open the project, go to settings, and then environment variables. There you can set variables for production, preview, and development.
According to their documentation that's the only way to achieve different Environment Variables based on the Environment (Development, Preview, or Production).
https://vercel.com/docs/build-step#environment-variables

Someone came up with a bash script to upload an .env file
while IFS== read -r name value
do
echo "$value" | vercel env add "$name" "$2"
done < "$1"
command:
<script name> <file> <production | preview | development>
and I also think it'd be better to have something like vercel env push [environment] [file]
SOURCE

Related

How to make production environmental variables with AWS Amplify and Next.js

I have an API key that I need to access an API endpoint. In my Next.js app, I store this key under .env.local like so:
API_KEY=qwerty123
And I access it in my getStaticProps function with the process.env:
const parkData = await fetch(
`${URL}parks?parkCode=${params?.parkCode}&limit=465&api_key=${process.env.API_KEY}`,
reqBody
)
When I try to run this in production I am getting an error that the API key is invalid. I know that the API is correct because when I run the project locally, the API data loads.
"code": "API_KEY_INVALID",
"message": "Your API key is not valid. Please get a new one at https://www.nps.gov/subjects/developer/get-started.htm"
My question is do I need to change how I call the API key in my getStaticProps function for the production build?
Note: I've made sure to included the env in the Amplify console.
Environment variables are not carried through to Lambda functions
For some reason, I'm not sure why myself, you still have to add the env's in your next.config.js file.
module.exports = {
env: {
MY_ENV_VAR: process.env.MY_ENV_VAR
}
};
Amplify troubleshooting docs

React app + heroku server not working on production, but working fine in dev

I am working on React application which is querying from a server. I have deployed the server on heroku. When I am testing in dev, the application is behaving as expected. But when I am using it on vercel deployment, it is failing as heroku server is not responding properly.
Following is the server code of the query:
app.get(`/allPlans`, async (req, res) => {
console.log("allPlans() query");
ret = await Plans.find({});
f = [];
for (i = 0; i < ret.length; i++) {
f.push(ret[i].name);
}
console.log(f);
return res.status(200).send(f);
});
Folowing is the code I am using to query from the client using axios:
const endPoint = "/allPlans";
let ret = await axios.get(endPoint);
console.log(ret.data);
In the dev environment, when I am deploying the application on localhost:3000, this is returning me a nice array.
["test","myPlan190","myPlan987"]
But in the actual production on vercel it is returning the following object(You can check this message in the console by going on the vercel deployment):
All suggestions are welcome.
Github repo
Vercel deployment
Server status
Heroku server query which is failing from axios, but working elsewise
Well, I checked you repository and also checked the XHR requests on your Vercel deployment and as far as I can see it making only one, which is:
Request URL: https://planner-pcrsehfg3-akcgjc007.vercel.app/allPlans
It is not making an actual call to the server. I see that in Dashboard.js you are requiring axios from the package. I did not find any created instance of axios. So essentualy there is nothing to append in front of "/allPlans". Either create an axios instance with the right url "https://cryptic-bayou-91116.herokuapp.com" of just test it by putting the whole url "https://cryptic-bayou-91116.herokuapp.com/allPlans" inside the axios call in Dashboard.js.
Following is the updated code for an axios query:
const baseURL = "https://cryptic-bayou-91116.herokuapp.com"
...
const endPoint = baseURL + "/allPlans";
let ret = await axios.get(endPoint);
console.log(ret.data);
fHeroku randomly changed application binding port.
You may set port by:
const port = process.env.PORT || 3000
for this use in you app dotenv
Or edit file .env on heroku. Install Heroku CLI:
heroku login
heroku run bash -a app_name
touch .env
echo "PORT=3000" >> .env
check variable by
cat .env

NextJs: The Serverless Function exceeds the maximum size limit of 50mb

I'm new working with NextJs and when trying to deploy my project to Vercel I'm getting the following error:
Error! The Serverless Function "api/auth" is 50.55mb which exceeds the maximum size limit of 50mb.
I have spent a lot of my time trying to find a proper answer but I didn't find any. Here is the code of the api request I'm making:
const { auth: adminAuth } = require("firebase/admin");
export default async function auth(req, res) {
const tokenId = req.query.token;
return new Promise((resolve) => {
adminAuth
.verifyIdToken(tokenId)
.then((user) => {
res.json(user);
resolve();
})
.catch(() => {
res.status(302).send("Invalid authentication");
resolve();
});
});
}
I'll be really grateful if anybody can help me, thanks y'all!
I've been dealing with the same issue. It appears that when bundling the serverless function vercel is pulling in ALL assets within your project. So 50.55MB is likely the size of your current entire build. I'm researching how to only include certain files within the vercel.json but have so far not figured exactly how to do that. For now you could probably just remove a few files from your public assets to get under the limit.
This is likely caused by firebase/admin including everything in the firebase package, not just the "admin" parts.
You can verify this by creating a file with only the import and running #vercel/nft to trace the files.
npm init -y
npm add firebase
echo "const { auth: adminAuth } = require('firebase/admin')" > index.js
npm i -g #vercel/nft
nft print index.js
The entire firebase package is quite large, so its best to follow the recommendation from the firebase team and use the firebase-admin package inside Serverless Functions.
This SDK (firebase) is intended for end-user client access from environments such as the Web, mobile Web (e.g. React Native, Ionic), Node.js desktop (e.g. Electron), or IoT devices running Node.js. If you are instead interested in using a Node.js SDK which grants you admin access from a privileged environment (like a server), you should use the Firebase Admin Node.js SDK (firebase-admin).
source: firebase NPM
You could add .vercelignore file to avoid this
Ref: https://vercel.com/guides/prevent-uploading-sourcepaths-with-vercelignore
# Ignore everything (folders and files) on root only
/*
!api
!vercel.json
!*.html
!*.css

How do I configure my React-Node App so I can deploy it to Heroku?

So I've built a simple MERN app using create-react-app, that I want to deploy to Heroku. I build the front end in a client folder operating on localhost:3000, that sends requests to my express sever as a proxy to localhost:5000. My file structure is as follows:
+client
|
+-node_modules
+-public
+-src
|
+-components
+-App.js
+-index.js
//server
+-models
+-node-modules
+-package-lock.json
+-package.json
+-server.js
And I've set up the proxy in my package-json like this: "proxy": "http://localhost:5000",
So my main question is this: How do I configure my API endpoints for deployment?
At the moment, they're structured like this:
API call from react component:
useEffect(() => {
axios.get("http://localhost:5000/api/all-cafes")
.then((cafe) => {
setCafe(cafe.data);
})
.catch((err) => {
console.log(err);
})
}, [])
Express function on server.js
app.get('/api/all-cafes', (req,res) => {
Cafe.find()
.then((result) => {
res.send(result)
})
.catch(err => {
console.log(err)
})
})
My other question is what is the role of the .env file, and will I need to make one in order to solve this?
I've had a helpful suggestion saying that I can run the front end and back end on different servers, and adjust the code depending on whether it is in development or production, using the following code:
const prefix = process.env.NODE_ENV === 'production' ? "http://heroku_app_address" : "http://localhost:5000"
function getUrl(relativeUrl) {
return prefix + "/" + relativeUrl;
}
fetch(getUrl('api/all-reviews'));
But I'm not sure how to implement this, whether I need a .env file, and if so, what to put in said file.
The .env file helps you specifiy certain credentials or endpoints that are either going to change based on deployment environment (dev,qa,prod may have differewnt API endpoints), or you want to provide certain secret keys or configurations, which otherwise should not be part of your code repository (clientSecret etc).
The create-react-app.dev/docs has detailed explanation to these.
If you have not bootstraped your app using create-react-app then you can use dot-env npm package. The steps are detailed here: Stack overflow :Adding an .env file to React Project

Simple password-protection for React app on Heroku

I have a simple React app, created with create-react-app, that I'd like to deploy to Heroku (or somewhere easy) and password-protect. The protection can be really simple—just a single password is fine.
I started looking into HTTP basic auth but didn't find an easy answer. The closest I found was in this post, but (a) I don't love the idea of having to eject my app, and (b) I couldn't get it working. I was hoping I could find a Heroku plugin, but no luck there either.
It wouldn't be too hard to write a component that wraps my app and requests a password before showing it. The problem is that it executes client-side. I want to store the correct password server-side (or a hash thereof), and have the app send password attempts up to the server.
Since create-react-app operates on top of Node, I'm hoping there's an easy way to tell it to execute and store certain things on the server, but maybe I'm wrong. Any suggestions?
This create-react-app buildpack seems to support http basic auth:
https://github.com/substantial/create-react-app-buildpack
https://elements.heroku.com/buildpacks/substantial/heroku-buildpack-static
I am assuming your intentions are wanting to protect the config vars in heroku so other people cannot access you database with your credentials.
The way I password protected my deployment to heroku, is to make a keys_prod.js file containing the Heroku config vars of my mLab database in my backend using express and mongoDB:
keys_prod.js file:
module.exports = {
mongoURI: process.env.MONGO_URI,
secretOrKey: process.env.SECRET_OR_KEY
};
keys.js file:
if (process.env.NODE_ENV === 'production') {
module.exports = require('./keys_prod');
} else {
module.exports = require('./keys_dev');
}
in my server.js file I added:
// DB Config
const db = require('./config/keys').mongoURI;
// Server static assets if in production
if (process.env.NODE_ENV === 'production') {
// Set static folder
app.use(express.static('client/build'));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
This allows you to request the config vars you filled in heroku without including it in your repo.
If you use Node in backend you can use Passport Basic Auth
app.get('*', passport.authenticate('basic', { session: false }), (req, res) => {
res.sendFile(path.join(`${__dirname}/../build/index.html`))
})
Every time you access the page in browser, a popup will appear, asking you username and password.

Resources