This is a follow up to my first part on creating your self hosted Linktree
Introduction
In the first part, we have created our frontend for the Linktree. In this part, I cover analytics and deployment to Vercel
Let's get started!
Part 1: Creating the serverless function
So far, you have should have your Linktree running in your browser on localhost:3000
Now, we begin by creating the serverless function
Step 1:
Let’s begin by adding MongoDB to our project. Run
npm i mongodb --save
in the terminal. We are going to be saving our visitors data to this DBStep 2:
Create a new folder called
api
in the root directory of your project and create a file called log.js
This is where we write our serverless function. Open this file in VS Code
Step 3:
We first import two modules we need
const url = require("url");
const MongoClient = require("mongodb").MongoClient;
The first module,
url
is needed to parse the MongoDB URI which we’ll be using later onStep 4:
We then create two variables we need
let cachedDb = null;
const uri = process.env.VISITORSDB;
cachedDb
will hold our database object, while uri
will store the MongoDB connection string from an environment variableNext, we write a function to connect to MongoDB
Step 5:
async function connectToDatabase()
{
if(cachedDb){
return cachedDb;
}
const client = await MongoClient.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const db = await client.db(url.parse(uri).pathname.substr(1));
cachedDb = db;
return db;
}
The above function connects to MongoDB and assigns the cachedDb variable the object of the database.
Step 6:
Now we export the serverless function which will actually store the data to the database
module.exports = async (req, res) => {
try {
console.log("Inside default log function");
const referer = req.headers["referer"];
const ip = req.headers["x-forwarded-for"];
const ua = req.headers["user-agent"];
const ul = req.headers["accept-language"];
const dnt = req.headers["dnt"];
const reg = req.headers["x-vercel-id"];
d = new Date().toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' });
info = {ip, ua, ul, dnt, referer, reg, dt: "" + d};
const db = await connectToDatabase();
const collection = await db.collection(process.env.COLLECTION);
await collection
.insertOne(info)
.then(() => {
res.status(200).send();
})
.catch(err => {
throw err;
});
}
catch(error)
{
console.log(error);
res.status(500).send();
}
};
When our function is called, we get a request and response object passed to our function. The request object contains the headers, which are sent to our Vercel deployment on every request. You can read more about them here
I’ll explain the function part by part
const referer = req.headers["referer"];
const ip = req.headers["x-forwarded-for"];
const ua = req.headers["user-agent"];
const ul = req.headers["accept-language"];
const dnt = req.headers["dnt"];
const reg = req.headers["x-vercel-id"];
In the first part, we extract data from the headers including the user’s IP address and user agent.
d = new Date().toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' });
Here, we create a new Date object to get the current date and time which will then be saved to the database. The timezone parameter converts the time into our local time.
const db = await connectToDatabase();
const collection = await db.collection(process.env.COLLECTION);
In the above line, we connect to the database.
A collection is like a table in MongoDB. You can read more about it here
info = {ip, ua, ul, dnt, referer, reg, dt: "" + d};
Here, we create a JSON object which contains all the data to be written to the database
Now the fun part - we write the data to MongoDB
await collection
.insertOne(info)
.then(() => {
res.status(200).send();
})
.catch(err => {
throw err;
});
}
catch(error)
{
res.status(500).send();
}
The above code writes the
info
object to MongoDB. If it succeeds, we get a HTTP 200 response, or if it fails we get a HTTP 500 response.Our serverless function is now ready to start recording analytics. Now let’s put it all together and deploy it!
Part 2: Deployment to Vercel
Step 1: Putting it all on Git
Create an account on GitHub (if you don’t have one already) and set up Git on your PC using these steps.
Create a new repository and push your code. If you haven’t used Git before, I suggest this tutorial.
Step 2: Create a free MongoDB Atlas account
Set up a MongoDB account and a free cluster by following these steps.
In the Add your IP address section, add
0.0.0.0/0
so the database can be accessed by all IP addresses. This is necessary to ensure you can connect and read data from AtlasFinally, create a database user and make sure you note down the username, password and the connection string as you’ll need it in the next step
Step 2: Create an account on Vercel
Head over to Vercel and choose sign in with GitHub. You may have to enter your phone number for an OTP. Once done, click on New Project → Choose your GitHub repository and click import. Leave all options as they are, Vercel will auto configure the build environment
Open the section on Environment Variables, and add a variable called
COLLECTION
the value of which will be the collection name in MongoDB.Add another environment variable called
VISITORSDB
and add the connection string which you got from the earlier step. Make sure to replace <password>
with your MongoDB user password!And deploy!
With everything done, you can finally click on deploy. Wait for a minute or so until the deployment is done. Once done, you’ll get an URL which you can use to access your project.
How do you check your analytics?
That’s simple - just download MongoDB Compass and use the same connection string as above to login. Once connected, click on the collection name on the left and you should see your database with access logs.
And it’s a wrap!
If you have followed along till here, you should have your Linktree deployed on Vercel with analytics enabled. I hope you enjoyed working on your own Linktree as much as I enjoyed writing this tutorial. If you have any doubts, you can reach out to me using my socials on the homepage
As always, happy hacking!
Loading Comments...