I’ll show you how to quickly and easily build an Instagram gallery with image popup in just one single PHP file. You will learn a bit of PHP, HTML, Bootstrap and JavaScript / jQuery. At the end of the tutorial you will have a file that you can use directly for your project or website. I also prepared a little demo on my webserver.

Did you know that you can easily read the last 12 posts of a public Instagram profile without any API? There are also other data available, such as: the number of followers. The creativity in programming applications with these constantly updated and structured data is almost limitless.

Demo of the Instagram gallery

The gallery should be able to:

  • show up to 12 Instagram post images
  • be responsive (bootstrap)
  • show different Instagram profiles via the GET parameter “user”

Here’s what you need

Ready? Let’s get started with the PHP code!

Create a text file called “index.php” and add the PHP-Code. Here’s what it does:

  1. Set document header to UTF-8 to prevent problems with special chars
  2. Validate the GET-Parameter you can add to the URL to show different Instagram profiles
  3. Put all filtered variables into the handy little $get var
  4. If no GET-Parameter is given, define the default profile, in this case “ladygaga”
  5. Read the URL directly with PHP CURL from Instagram
  6. Decode the JSON result and save it as the variable “$data” for usage in HTML
// Set the PHP header to UTF-8, to show all special characters
header('Content-type: text/html; charset=utf-8');

// Filter
$get_arguments = [

// Put all filtered variables into the handy little $get var
$get = filter_input_array(INPUT_GET, $get_arguments);

// Check if the user is set and create the url
    $url = 'https://www.instagram.com/'.$get['user'].'/?__a=1';
    $url = 'https://www.instagram.com/ladygaga/?__a=1';

// Initiate and execute CURL to request the URL
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL,$url);
$result = curl_exec($ch);

// Transform the Instagram JSON result into a PHP array
$data = json_decode($result, true);

That was easy, right? In the last line of the PHP code you can check via “print_r”, whether the data was correctly read out from Instagram. You can also call the link directly at any time, e.g. so: https://www.instagram.com/panamatravellers/?__a=1

Let’s continue with the HTML code

Right after the PHP code, you can add the following HTML code. It contains all the necessary HTML, CSS and JavaScript we need to create the gallery.

<!DOCTYPE html>
        <title>Instagram Gallery</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/magnific-popup.min.css" integrity="sha256-PZLhE6wwMbg4AB3d35ZdBF9HD/dI/y4RazA3iRDurss=" crossorigin="anonymous" />
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
                height: 100%;
                background-image: linear-gradient(to right top, #051937, #004d7a, #008793, #00bf72, #a8eb12);
                background-size: cover;
                background-position: top center;
                background-repeat: no-repeat;
    <body class="bg-dark text-white">
        <h1 class="text-center my-5">Instagram Gallery</h1>
        <div class="container my-5">
            <div class="row no-gutters bg-dark text-light">
                <div class="col-sm-4 p-3">
                <div class="col-sm-8 p-3">
            <div class="row no-gutters">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.js" integrity="sha256-wk7QMTzYE7BJvko9BsywPzRmKzhCtIQKTuN6/B9sRmw=" crossorigin="anonymous"></script>
                type: 'image',
                closeOnContentClick: true,
                image: {
                    verticalFit: true
                gallery: {
                    enabled: true,
                    navigateByImgClick: true,
                    preload: [0,1]

Output of the data with some extra PHP code

To make the HTML skeleton dynamic, we still need some inline PHP code.

Display the current profile name in the browsers tab / page title.

// Replace this:
<title>Instagram Gallery</title>

// With this:
<title><?php echo $data['graphql']['user']['full_name']; ?> - Instagram Gallery</title>

Add some information and a link to the users profile

Replace the placeholder ###USERNAME### with the code below.

<h2 class="text-white mb-0"><?php echo $data['graphql']['user']['full_name']; ?></h2>
<a href="https://instagram.com/<?php echo $data['graphql']['user']['username']; ?>" target="_blank">
    <small>@<?php echo $data['graphql']['user']['username']; ?></small>

Show description and external URL of the current profile

Replace the placeholder ###DESCRIPTION### with the code below.

<p class="mb-0"><?php echo $data['graphql']['user']['biography']; ?></p>
<small><?php echo '<a href="'.$data['graphql']['user']['external_url'].'" target="_blank">'.$data['graphql']['user']['external_url'].'</a>'; ?></small>

Finally output the images!

The last piece of code goes here! It’s a loop and it checks if there is some content available before showing anything. If no data is found, it outputs an alert message “No posts found, or profile not accessible!”

Replace the placeholder ###IMAGES### with the code below.

// Finally output the $data array if it exists. Otherwise write an alert!
    foreach ($data['graphql']['user']['edge_owner_to_timeline_media']['edges'] as $post) {
        echo '<div class="col-4 col-sm-3 col-md-2">';
        echo '<a href="'.$post['node']['display_url'].'" class="popup">';
        echo '<img class="img-responsive w-100" src="'.$post['node']['thumbnail_resources'][0]['src'].'">';
        echo '</a>';
        echo '</div>';
    echo '<div class="alert alert-info">No posts found, or profile not accessible!</div>';

Published by typo3freelancer

Web Developer, Outdoor-Freak, specialized in TYPO3 Content Management, but also highly interested in all the other crazy stuff out there!

Leave a comment

Your email address will not be published. Required fields are marked *