How to Create a URL Shortener Like Bit.ly in Laravel 8

How to Create a URL Shortener Like Bit.ly in Laravel 8

Admin
Admin・ 21 Oktober 2021
10 min read ・ 3498 views

Laravel URL Shortener - I'm sure you are familiar with URL shortening websites or URL Shorteners such as bit.ly or s.id. Short URLs will greatly facilitate the distribution of these URLs and are also easy to remember. Well, in this article, I will share how to make a URL shortener using the URL shortener package in Laravel 8.

In this article, I will use the Short URL package from Ash Allen which has several features such as; custom URL key, tracking visitors, activation and deactivation time, and others.

Okay, let's get straight to coding. 🚀 👇

Step 1: Install Laravel

//via Laravel Installer
composer global require laravel/installer
laravel new laravel-url-shortener

//via Composer
composer create-project laravel/laravel laravel-url-shortener

In this first step, we need to install the latest version of laravel (currently version 8) which we will try to implement to create a URL shortener like s.id or bit.ly in laravel 8. To install laravel you can use laravel installer or use composer like the example above.

Please choose one method you want to use for laravel installation. From the two examples of laravel installation commands above, they will both generate a laravel project with the name laravel-url-shortener.

Step 2: Install Laravel URL Shortener Package

composer require ashallendesign/short-url

Then, go to the project directory and install the short URL package by running the command as above via composer.

php artisan vendor:publish --provider="AshAllenDesign\ShortURL\Providers\ShortURLProvider"

Run the php artisan vendor:publish command as above to publish the config file and migration from the package's short URL.

Step 3: Setup Database

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_url_shortener
DB_USERNAME=root
DB_PASSWORD=

Next, create a new database to store sample data that we will use in this experiment. If you are using xampp as local development, please create a new database at localhost/phpmyadmin. Here I give an example, I created a new database with the name Laravel_url_shortener. Then don't forget to also adjust the DB_DATABASE in the .env file as in the example above. And then run the command php artisan migrate, to migrate all migration files to the database.

Step 4: Define Route & Logic

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    $urls = \AshAllenDesign\ShortURL\Models\ShortURL::latest()->get();
    return view('welcome', compact('urls'));
});

Route::post('/', function () {
    $builder = new \AshAllenDesign\ShortURL\Classes\Builder();

    $shortURLObject = $builder->destinationUrl(request()->url)->make();
    $shortURL = $shortURLObject->default_short_url;

    return back()->with('success','URL shortened successfully. ');

})->name('url.shorten');

Route::post('{id}', function ($id) {
    $url = \AshAllenDesign\ShortURL\Models\ShortURL::find($id);
    $url->url_key = request()->url;
    $url->destination_url = request()->destination;
    $url->save();

    return back()->with('success','URL updated successfully. ');
})->name('update');

Fourth step, open the routes/web.php file and we update the default route from laravel and add two new routes as above. The first route, serves to display the welcome.blade.php view file along with URL data that has been successfully added or shortened using Laravel URL shortener. The second route with the POST method, serves to add data URLs that have been shortened. And the third route with the POST method, serves to update or store data changes that have been made.

Step 5: Setup View

<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- Bootstrap CSS -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
        <title>Laravel 8 URL Shortener</title>
    </head>
    <body>
        <div class="container my-5">
            <div class="row">
                <h1 class="my-2 fs-4 fw-bold text-center">Laravel URL Shortener</h1>
                <form action="{{ route('url.shorten') }}" method="POST" class="my-2">
                    @csrf
                    <div class="input-group mb-3">
                        <input type="text" name="url" class="form-control" placeholder="URL Shortener">
                        <button class="btn btn-outline-secondary" type="submit">Shorten</button>
                    </div>
                </form>
                @if (session('success'))
                <div class="alert alert-success alert-dismissible fade show" role="alert">
                    {{ session('success') }}
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                </div>
                @endif
                <table class="table">
                    <thead>
                        <tr>
                            <th scope="col">#</th>
                            <th scope="col">URL Key</th>
                            <th scope="col">URL Destination</th>
                            <th scope="col">Short URL</th>
                            <th scope="col">Visitors</th>
                            <th scope="col">action</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach ($urls as $key => $item)
                        <tr>
                            <th scope="row">{{ ++$key }}</th>
                            <td>{{ $item->url_key }}</td>
                            <td>{{ $item->destination_url }}</td>
                            <td>{{ $item->default_short_url }}</td>
                            <td>{{ $item->visits->count() }}</td>
                            <td>
                                <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal-{{ $key }}">
                                Edit
                                </button>
                            </td>
                        </tr>
                        <!-- Modal -->
                        <div class="modal fade" id="exampleModal-{{ $key }}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
                            <div class="modal-dialog">
                                <div class="modal-content">
                                    <div class="modal-header">
                                        <h5 class="modal-title" id="exampleModalLabel">Edit</h5>
                                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                                    </div>
                                    <div class="modal-body">
                                        <form action="{{ route('update', $item->id) }}" method="POST">
                                            @csrf
                                            <div class="mb-3">
                                                <label for="key" class="form-label">URL Key</label>
                                                <input type="text" name="url" value="{{ $item->url_key }}" class="form-control" id="key">
                                            </div>
                                            <div class="mb-3">
                                                <label for="destination" class="form-label">Destination URL</label>
                                                <input type="text" name="destination" value="{{ $item->destination_url }}" class="form-control" id="destination">
                                            </div>
                                            <button type="submit" class="btn btn-primary">Update</button>
                                        </form>
                                    </div>
                                </div>
                            </div>
                        </div>
                        @endforeach  
                    </tbody>
                </table>
            </div>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
    </body>
</html>

Then, open the view welcome.blade.php file and update the existing code to be like the code above. With the code as above, we will use bootstrap 5 and add a table with the contents of the data from the short_urls table. In addition, we also have a form to add data and a form in the modal to edit URL data.

Step 6: Testing 1

Alright, it's time to test the first URL shortener feature. Please run your laravel project with php artisan serve command, then open laravel project in browser with URL 127.0.0.1:8000 or laravel-url-shortener.test. For the first test, try entering the URL and clicking shorten, then the data will be stored in the short_urls table.

Laravel URL Shortener

Example: Here I try to shorten or shorten the URL by inputting the URL https://codelapan.com/post/sentry-for-monitoring-dan-error-tracking-di-laravel-8 then I click shorten. So now, if I try to access the URL 127.0.0.1:8000/short/asdsa in the browser, I will be redirected to the URL that was inputted earlier.

Here, we can also edit the URL key as originally asdsa was changed to abc12. So, when the URL 127.0.0.1:8000/short/abc12 is accessed it will be redirected to the destination url or destination url.

What if we want a custom route like example.com/id/asVc2 ? the answer is below. 👇

Step 7: Custom Route

Confg/short-url.php

'disable_default_route' => true,

To do a custom route, open the config/short-url.php file and change the value from disable_default_route to true.

vendor/ashallendesign/short-url/src/Classes/Builder.php

'default_short_url'              => config('app.url').'/short/'.$this->urlKey,

Then open the Builder.php file in the vendor/ashallendesign/short-url/src/Classes directory, find the code as above and change it to the code below.

'default_short_url'              => config('app.url').'/id/'.$this->urlKey,

Here, we change the value of the default_short_url field which was originally valued at domain.com/short/{URL key} to domain.com/id/{URL key}.

routes/web.php

Route::get('/id/{shortURLKey}', '\AshAllenDesign\ShortURL\Controllers\ShortURLController');

Then, open the routes/web.php file, then add a new route like the code above.

$url->default_short_url = config('app.url').'/id/'.request()->url;

Also add the code as above in the update route, so that the current update route becomes like the code below.

Route::post('{id}', function ($id) {
    $url = \AshAllenDesign\ShortURL\Models\ShortURL::find($id);
    $url->url_key = request()->url;
    $url->destination_url = request()->destination;
    $url->default_short_url = config('app.url').'/id/'.request()->url;
    $url->save();

    return back()->with('success','URL updated successfully. ');
})->name('update');

Step 8: Testing 2:

Laravel 8 URL shortener

OK, now it's time for another second test. Please try again to input a new URL and click Shorten, then the result is that the default short url has changed the format to domain.com/id/{URL key} as shown above.

If you have another easier or better way, you can share it in the comment form below. Hopefully this article can be useful and see you in the next article.👋 

 

📖 Full Documentation: Laravel URL Shortener

Tinggalkan Komentar
Loading Comments