How to Build a Link-shortening App with React and Bitly API.
Frank Otabil Amissah
Posted on March 19, 2023
Link shortening is a way to reduce an excessively long URL into a short URL using link management software.
In this tutorial, I teach how to make a link shortener using the Bitly API and React.
Here's a demo of the app.
Bitly is a URL-shortening service and a link management platform.
-Bitly
React is a javascript front-end library for making user interfaces.
Note: This tutorial uses node v18, and react v18.
let's dive in.
Bootstrapping a new react app.
Run the code below in your terminal to start a new react project:
npx create-react-app app_name
The command automatically creates a folder with the name specified for the project.
After react app is set up successfully, navigate into your react project directory by running:
cd app_name
In your project directory, install React-copy-to-clipboard by running the following command in your terminal:
npm install react-copy-to-clipboard
Now, run the following command to view your application on localhost:3000.
npm run start
Restructuring project directory
Open your text editor and structure your ./src directory to look like so,
|--/src
| |--/icons
| |--Home.css
| |--Home.js
| |--index.css
| |--index.js
You may delete App.test.js
, setupTest.js
, and reportWebVitals.js
from your directory as you'll not need them in this tutorial.
icons folder will contain icons you'll use in the app.
Making the UI component.
Add the following code to your /src/Home.js
file:
import { useState } from "react";
import { CopyToClipboard } from "react-copy-to-clipboard";
import "./Home.css";
import send from './icons/send.png';
import copyicon from './icons/copy.png';
import copiedicon from './icons/copied.png';
function Home() {
const [longURL, setLongUrl] = useState("");
const [shortLink, setShortLink] = useState({});
const [active, setActive] = useState(false);
const [copy, setCopy] = useState(false);
function handleChange(e) {
setLongUrl(e.target.value);
}
async function handleSubmit(e) {
e.preventDefault();
await fetch("https://api-ssl.bitly.com/v4/shorten", {
method: "POST",
mode: "cors",
headers: {
Authorization: `Bearer ${process.env.REACT_APP_BITLY_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
long_url: longURL,
domain: "bit.ly",
group_guid: `${process.env.REACT_APP_GUID}`,
}),
})
.then((res) => res.json())
.then((data) => {
const new_link = data.link.replace("https://", "");
fetch(
`https://api-ssl.bitly.com/v4/bitlinks/${new_link}/qr?image_format=png`,
{
mode: "cors",
headers: {
Authorization: `Bearer ${process.env.REACT_APP_BITLY_TOKEN}`,
},
}
)
.then((response) => response.json())
.then((result) => {
setShortLink(result);
setActive(true);
});
});
setLongUrl("");
}
return (
<div className="App">
<h2>A Simple Bitly Link Shortener</h2>
<div>
<form method="post" action="" onSubmit={handleSubmit}>
<input
name="long_url"
type="text"
value={longURL}
placeholder="Paste your url"
onChange={handleChange}
/>
<button type="submit"><img src={send} alt="send icon" id="send_icon"/></button>
</form>
</div>
{/* show on success... */}
{active ? (
<div className="show_links">
<img src={shortLink.qr_code} alt="Qr code" className="qr_img"/>
<div>
<h3>Here's your short link...</h3>
<span>
<p>{shortLink.link}</p>
<CopyToClipboard onCopy={()=>{
setCopy(true);
}} text={shortLink.link}>{ !copy ? <img src={copyicon} alt="copy icon" width="17px" height="17px"/> : <img src={copiedicon} alt="copy icon" width="17px" height="17px"/> }</CopyToClipboard>
</span>
</div>
</div>
) : (
""
)}
</div>
);
}
export default Home;
The async handleSubmit function
is called when we click the submit button. You'll notice that it contains two fetch methods, one contained in the other. The first fetch method submits the URL to bitly and passes the bit.ly link received in the response object to the second fetch method which is then used to request the QR code.
The handleChange function
is called to update the input field as we type.
Now, go to /src/index.js
and override its content with the following code.
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import Home from "./Home";
import reportWebVitals from "./reportWebVitals";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<Home />
</React.StrictMode>
);
reportWebVitals(console.log))
reportWebVitals();
The code blocks above imports and renders the home component in the root node.
Adding project icons.
Download the icons from Mediafire, unzip and paste its content in /src/icons
.
Styling the component.
Note: In this tutorial, we'll not focus on CSS so I prepared some CSS to add to the project.
In your /src/Home.css
file add the following code:
* {
margin:0;
}
.App {
width:100%;
height:100vh! important;
text-align:center;
background-color:rgb(207, 207, 207);
display:flex;
align-items:center;
justify-content:center;
flex-direction:column;
}
h2{
padding:0 0 20px;
font-size:2rem;
}
input[type=text] {
font-size: 1.2rem;
width: 300px;
height: 100%;
border-radius: 8px 0 0 8px;
background-color: rgb(233, 233, 233);
text-align: center;
padding: 10px 20px;
border: none;
}
input[type=text]:focus {
outline: none;
border: none;
}
button{
font-size:1.2rem;
box-sizing: border-box;
height:100%;
padding:10px 25px;
border:none;
border-radius:0 8px 8px 0;
}
button:hover{
background-color: rgb(39, 137, 179);
}
#send_icon{
width:21px;
height:1.2rem;
vertical-align: middle;
}
.show_links {
padding: 10px;
margin-top: 20px;
display: flex;
flex-direction: row;
column-gap: 20px;
align-items: flex-end;
background-color: rgb(233, 233, 233);
width:400px;
height:100px;
animation-name: fadeIn;
animation-duration: 3s;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.qr_img {
width: 100px;
height: inherit;
background-color: black;
color: white;
}
.show_links p {
width: 200px;
padding: 10px 15px;
text-align: left;
font-weight: 500;
border: 1.5px solid rgb(179, 179, 179);
border-radius: 8px;
}
span {
display: flex;
flex-direction:row;
padding: 10px 0;
column-gap: 15px;
justify-content: center;
align-items: center;
}
h3 {
text-align: left;
margin-bottom: 10px;
color: rgb(39, 137, 179);
}
/*for smaller devices */
@media (max-width:700px){
h2{
padding:0 0 20px;
font-size:1.3rem;
}
.show_links {
padding: 15px;
margin-top: 20px;
display: block;
width:200px;
height:300px;
}
.qr_img {
width: 200px;
height: 200px;
margin: auto;
}
h3 {
margin: 10px 0;
color: rgb(39, 137, 179);
font-size: 1.05rem;
}
input[type=text] {
font-size: 1rem;
width: 170px;
height: 100%;
border-radius: 8px 0 0 8px;
background-color: rgb(233, 233, 233);
text-align: center;
padding: 10px 20px;
border: none;
}
button {
font-size: 1rem;
}
#send_icon {
width: 1.05rem;
height: 1rem;
vertical-align: middle;
}
.show_links p {
width: 170px;
font-size:0.9rem;
}
span {
column-gap: 10px;
}
}
Override your ./src/index.css
file with the following code:
body {
margin: 0;
padding: 0;
box-sizing: border-box;
background-color: rgb(233, 233, 233);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
Setting up authentication token.
Now, go to Bitly.com and create an account if you don't already have one.
Login into your dashboard and navigate to Settings >> API
Enter your Password and generate your API token.
In your root directory, create a .env
file and add the following code:
REACT_APP_BITLY_TOKEN = 'enter authorization token here'
REACT_APP_GUID = 'enter guid here'
Guid can be copied from your Bitly account URL https://app.bitly.com/[guid_here]/bitlinks
.
Now, add .env to your .gitignore file.
Pushing Repo to GitHub.
Run
git init
in your projects directory to turn our local environment into a repository.Now, go on and log in to your GitHub account and make a new repository.
Back in your terminal let's connect the local repository to GitHub, run
git remote add origin <url to your GitHub repository>
.Change your branch to match the branch on GitHub by running
git branch -M main
.Run
git add --all
, to stage your files.Run
git commit -m "your_commit_message"
to commit your files.Finally, run
git push -u origin main
to push to GitHub.
Now, refresh your GitHub repo to reflect changes.
Deploying application on Netlify.
- Go to netlify.com and sign up for an account if you don't already have one.
Login and navigate to Sites from your dashboard.
Click "Import from GitHub" and connect Netlify to GitHub on the page that follows.
Next, authorize Netlify and select the repo you just created.
Next, Click "Deploy site" to build.
After a successful build, Netlify will automatically assign a name to your app, you can change that under Site overview >> Site settings tab >> "Change site name".
- Let's add our environment variables to Netlify. Copy the content of your .env file, go to Site settings >> Environment Variable >> "Add a variable" and select "Import from a .env file", paste your content and click "Import variable".
- Go to the Deploys tab, click "Trigger deploy" and redeploy to use the environment variables in your live app.
Conclusion.
That's it! If you've made it this far without an error then you have successfully built your link-shortening app. Hurray! ๐. I encourage you to deploy the application and share it with your friends, you can also share it with me on Twitter @amotabil8.
P.S. If you liked the project do react to my post and if you ran into an error do share a comment and I'll do my best to help you resolve it. โ๏ธ
Resources.
Here's a link to the GitHub repository.
Learn more about React.
Learn more about Bitly's API.
Learn more about Netlify.
Posted on March 19, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 9, 2024
October 2, 2024