DEV Community

Cover image for Unsplash API - How to make unsplash clone | Javascript tutorial
Modern Web
Modern Web

Posted on

Unsplash API - How to make unsplash clone | Javascript tutorial

Hello guys, In today's article you'll learn to create this unsplash clone. If you don't know what unsplash is, unsplash is a website/company which offers royalty free images for personal or business use. We'll today create this website using unsplash API. It's a great javascript project for beginner.

So, without wasting more time, let's start. To see project demo or you want a video tutorial. You can watch the tutorial below.

Video Tutorial

I appreciate if you can support me by subscribing my youtube channel.

Source Code

Code

So, let's start with our folder structure. You can see the files we'll use, below.

Unsplash API - Javascript Project

So, let's make our home page first.

Home Page

Header Section

In our home page, we have a beautiful header section. To create that. Open index.html file. Inside that, code these elements.

<header class="header-section">
        <div class="header-content">
            <h1 class="logo">logo</h1>
            <p class="sub-line">the best royalty free images you can find here.</p>

            <form action="search.html">
                <input type="text" autocomplete="off" name="search" class="search-box" placeholder="search image">
                <button class="search-btn" type="submit">search</button>
            </form>
        </div>
</header>
Enter fullscreen mode Exit fullscreen mode

Without CSS HTML is nothing, is't it. So, let's style our header element.

*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'roboto', sans-serif;
}

.header-section{
    width: 100%;
    height: 100vh;
    position: relative;
    background-image: url('../img/bg.png');
    background-size: cover;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
}

.logo{
    font-size: 80px;
    font-weight: 400;
    color: #fff;
    text-transform: capitalize;
}

.sub-line{
    color: #fff;
    padding: 20px 0 30px;
    font-size: 20px;
    text-transform: capitalize;
    word-spacing: 2px;
    position: relative;
    font-weight: 300;
}

.sub-line::after{
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 60%;
    height: 1px;
    background: #fff;
}

.sub-line::before{
    content: '';
    position: absolute;
    bottom: -5px;
    left: 50%;
    transform: translateX(-50%);
    width: 10px;
    height: 10px;
    background: #fff;
    border-radius: 50%;
}

.search-box{
    display: block;
    margin: 60px auto 20px;
    width: 100%;
    height: 40px;
    border-radius: 5px;
    padding: 10px;
    border: none;
    outline: none;
    text-transform: capitalize;
}

.search-btn{
    padding: 10px 30px;
    border-radius: 5px;
    text-transform: capitalize;
    border: none;
    outline: none;
    cursor: pointer;
    background: #0a1113;
    color: #fff;
}
Enter fullscreen mode Exit fullscreen mode

Those are lots of styling. After giving these CSS, we are done with our header section.

Output

Unsplash clone - Javascript Tutorial

Isn't it looking great.

Gallery Section

After header section, we have image recommendations or image gallery in our home page in mansory layout. To create mansory layout, first we need some elements or images.

After header section in index.html

<section class="gallery">
    <img src="img/img (1).png" class="gallery-img" alt="">
    <img src="img/img (1).png" class="gallery-img" alt="">
    <img src="img/img (1).png" class="gallery-img" alt="">
    <img src="img/img (1).png" class="gallery-img" alt="">
    <img src="img/img (1).png" class="gallery-img" alt="">
    <img src="img/img (1).png" class="gallery-img" alt="">
    <img src="img/img (1).png" class="gallery-img" alt="">
    <img src="img/img (1).png" class="gallery-img" alt="">
</section>
Enter fullscreen mode Exit fullscreen mode

For now create 8 image elements. And give them some styles.

/* gallery */

.gallery{
    width: 100%;
    padding: 40px;
    background: #fff;
    columns: 4;
    column-gap: 20px;
}

.gallery-img{
    width: 100%;
    height: 100%;
    object-fit: cover;
    margin-bottom: 20px;
    border-radius: 5px;
    cursor: pointer;
    background: #f9f9f9;
}
Enter fullscreen mode Exit fullscreen mode
Output

Unsplash Clone

If you create less than 8 images, you'll probably don't see images in 4 columns. This is because, we have used columns CSS property to create grid. Note - we are not using grid here, cause grid create a fixed size row and columns and we want images to have their proportions. Columns property is used to define columns for elements in CSS without using grid. This don't restrict you with fixed row height.

So, now you can remove the hard coded image elements from index.html. and let's make it with JS. So open app.js.

In app.js file, first you need to store your unsplash API key. If you don't know how to create one, then check this.

const access_key = 'your api key';
Enter fullscreen mode Exit fullscreen mode

Once you got your key, we need random photo url, so that we can get random photos, you can find the url in the unsplash documentation. but for your ease, here it is.

const random_photo_url = `https://api.unsplash.com/photos/random?client_id=${access_key}&count=30`;
Enter fullscreen mode Exit fullscreen mode

Here access_key is your api key. And I am using JS template literals here.

Now, make a function getImages. This function will make request to random photo URL.

let allImages; // this will store all the images

const getImages = () => {
    fetch(random_photo_url)
    .then(res => res.json())
    .then(data => {
        allImages = data;
        makeImages(allImages);
    });
}
Enter fullscreen mode Exit fullscreen mode

allImages will store the fetched data, so we can access the data after receiving it outside the function. So, now once we got the images, we need to make dynamic image elements, for that make makeImages function.

const gallery = document.querySelector('.gallery');

const makeImages = (data) => {
    data.forEach((item, index) => {

        let img = document.createElement('img');
        img.src = item.urls.regular;
        img.className = 'gallery-img';

        gallery.appendChild(img);

    })
}
Enter fullscreen mode Exit fullscreen mode

So, after this you should see random images being fetched from API and created with JS dynamically.

getImages()
Enter fullscreen mode Exit fullscreen mode

Make sure to call the function

Output

Unsplash Clone

Great! now, let's create image popup effect. For that again open your index.html file.

Image popup

Create image popup before gallery. Or you can it after also it doesn't really matters 😂

<!-- popup window -->
<div class="image-popup">
    <button class="close-btn"></button>
    <a href="#" class="download-btn">download image</a>
    <img src="img/img (1).png" class="large-img" alt="">
    <button class="controls pre-btn"><img src="img/pre.png" alt=""></button>
    <button class="controls nxt-btn"><img src="img/nxt.png" alt=""></button>
</div>
Enter fullscreen mode Exit fullscreen mode
/* image popup */

.image-popup{
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 80%;
    height: 80vh;
    background: #f9f9f9;
    box-shadow: 0px 5px 50px rgba(0, 0, 0, 0.25);
    border-radius: 10px;
    transition: .5s;
    display: flex;
    justify-content: center;
    align-items: center;
}

.image-popup.hide{
    display: none;
    opacity: 0;
}

.close-btn{
    position: absolute;
    top: 10px;
    left: 10px;
    width: 20px;
    height: 20px;
    background: #ff4f4f;
    border-radius: 50%;
    border: none;
    cursor: pointer;
}

.download-btn{
    text-transform: capitalize;
    padding: 10px 20px;
    background: #192f2e;
    color: #fff;
    text-decoration: none;
    border-radius: 5px;
    position: absolute;
    right: 10px;
    top: 10px;
}

.large-img{
    height: 80%;
    width: auto;
    max-width: 80%;
    object-fit: cover;
    border-radius: 10px;
}

.controls{
    background: none;
    border: none;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    cursor: pointer;
}

.pre-btn{
    left: 20px;
}

.nxt-btn{
    right: 20px;
}
Enter fullscreen mode Exit fullscreen mode
Output

Unsplash Clone

You can see in above styles, we have hide class which is setting display to none. So add hide class to image-popup element. You can also remove the image source from large-img

Now, let's make it functional with Javascript.

let currentImage = 0; // will track the current large image

const makeImages = (data) => {
    data.forEach((item, index) => {

        ..previous code..

        // popup image

        img.addEventListener('click', () => {
            currentImage = index;
            showPopup(item);
        })

    })
}
Enter fullscreen mode Exit fullscreen mode

This above code will add click event to all the images, so that we can open the popup. So, now let's create showPopup function.

const showPopup = (item) => {
    let popup = document.querySelector('.image-popup');
    const downloadBtn = document.querySelector('.download-btn');
    const closeBtn = document.querySelector('.close-btn');
    const image = document.querySelector('.large-img');

    popup.classList.remove('hide');
    downloadBtn.href = item.links.html;
    image.src = item.urls.regular;

    closeBtn.addEventListener('click', () => {
        popup.classList.add('hide');
    })

}
Enter fullscreen mode Exit fullscreen mode

In this function, first we are selecting all the HTML elements using querySelector method. And then removing hide class from popup element. also setting up download image btn link along with image source. And yes, we are also add close functionality.

So, we just have to make controls now.

// controls

const preBtns = document.querySelector('.pre-btn');
const nxtBtns = document.querySelector('.nxt-btn');

preBtns.addEventListener('click', () => {
    if(currentImage > 0){
        currentImage--;
        showPopup(allImages[currentImage]);
    }
})

nxtBtns.addEventListener('click', () => {
    if(currentImage < allImages.length - 1){
        currentImage++;
        showPopup(allImages[currentImage]);
    }
})
Enter fullscreen mode Exit fullscreen mode

Above code is also very simple. In above code, we are selecting the previous and next buttons and adding click event to them. Inside the events, I am checking for condition to validate end image.

So great. We are done with our home page. Let's create our search page now.

Search Page

Our search page is very simple. To start, copy all the elements from index.html except header section. and paste it inside this file. After done with that, make a search box at the very start of body tag.

<form action="search.html" class="search-container">
    <input type="text" autocomplete="off" name="search" class="search-input" placeholder="search image">
    <button class="search" type="submit">search</button>
</form>
Enter fullscreen mode Exit fullscreen mode

Make sure you link search.css & app.js file to it. Now, add these form styles to search.css.

.search-container{
    width: 100%;
    height: 60px;
    background: #0a1113;
    padding: 10px 40px;
    display: flex;
    justify-content: space-between;
}

.search-input{
    width: 95%;
    height: 40px;
    border-radius: 5px;
    border: none;
    outline: none;
    padding: 20px;
    text-transform: capitalize;
}

.search{
    background: none;
    border: none;
    color: #fff;
    text-transform: capitalize;
    cursor: pointer;
}
Enter fullscreen mode Exit fullscreen mode

After all of this, you should see something like this.

Output

Unsplash Clone

Now, let's fetch images related to search keyword. Inside app.js

let searchParam = location.search.split('=').pop(); // this will give extract the search keyword from URL

const search_photo_url = `https://api.unsplash.com/search/photos?client_id=${access_key}&query=${searchParam}&per_page=50`; // this is search image URL
Enter fullscreen mode Exit fullscreen mode

Now, create a function to make request to the URL.

const searchImages = () => {
    fetch(search_photo_url)
    .then(res => res.json())
    .then(data => {
        allImages = data.results;
        makeImages(allImages);
    });
}
Enter fullscreen mode Exit fullscreen mode

After this, we just need to check we are on home page or search page and call the function according to it. So instead of calling simple getImages(); wrap that to this condition along with this code.

if(searchParam == ''){
    getImages();
} else{
    searchImages();
}
Enter fullscreen mode Exit fullscreen mode

So above condition is simple when we open home page, our searchParam will be an empty string. That's why I am comparing that to check for the page.

Output

Unsplash Clone

I searched for cars

So, that's it. Great work guys. We are done with the project. So, how is this project, and did you learn something new from this.

I hope you understood each and everything. If you have doubt or I missed something let me know in the comments.

Articles you may find Useful

  1. Best CSS Effect
  2. Infinte CSS loader
  3. Disney+ Clone
  4. Youtube API - Youtube Clone
  5. TMDB - Netflix Clone

I really appreciate if you can subscribe my youtube channel. I create awesome web contents.

Source Code
Thanks for reading

Oldest comments (3)

Collapse
 
thomasbnt profile image
Thomas Bnt ☕

Cool project ! Don't hesitate to check 👍🏼📸

#unsplash

📸 Over 3 million free high-resolution images brought to you by the world’s most generous community of photographers. — You can use their API for making beautiful websites for free.
Collapse
 
spandan profile image
Spandan

Amazing and awesome post this is .
Good going
Keep it up.

Collapse
 
abhishekrajputweb profile image
abhishekrajput-web

Helpful thanks for sharing