Get started with 33% off your first certification using code: 33OFFNEW

How to build a URL shortener in Laravel

6 min read
Published on 11th June 2024

Creating a URL shortener service is a fantastic way to dive into web application development with Laravel, one of the most popular PHP frameworks. This tutorial will guide you through setting up a basic URL shortener, from initializing the project to deploying it. We will cover everything you need, including setting up routes, controllers, models, and views, as well as integrating database functionality.

Introduction

A URL shortener takes a long URL and provides a shorter, unique URL that redirects to the original URL. These services are handy for social media, SMS messages, and any situation where a shorter URL is more convenient. In this tutorial, we will build a simple URL shortener service using Laravel.

Setting Up Laravel

First, ensure you have Composer installed on your system. Composer is a dependency manager for PHP. If you don’t have it installed, you can download it from getcomposer.org.

  1. Install Laravel via Composer:

    composer create-project --prefer-dist laravel/laravel url-shortener
    
  2. Navigate to the project directory:

    cd url-shortener
    
  3. Serve the application:

    php artisan serve
    

    Your Laravel application should now be running on http://127.0.0.1:8000.

Database Configuration

We need to set up the database connection. Laravel supports various database systems; we will use MySQL for this tutorial.

  1. Create a database: Create a new database using your preferred method (e.g., phpMyAdmin, MySQL Workbench, or command line).

  2. Configure the .env file: Update the database configuration in the .env file:

    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=url_shortener
    DB_USERNAME=root
    DB_PASSWORD=your_password
    

Creating the URL Model and Migration

Laravel’s Eloquent ORM makes it easy to interact with your database. We will create a model for our URLs along with a migration to create the database table.

  1. Generate the model and migration:

    php artisan make:model Url -m
    
  2. Define the migration: Open the migration file in database/migrations/ and update the up method:

    public function up()
    {
        Schema::create('urls', function (Blueprint $table) {
            $table->id();
            $table->string('original_url');
            $table->string('short_url')->unique();
            $table->timestamps();
        });
    }
    
  3. Run the migration: Apply the migration to create the urls table in your database:

    php artisan migrate
    

Building the Controller

The controller will handle the logic for creating and managing short URLs.

  1. Generate the controller:

    php artisan make:controller UrlController
    
  2. Define the controller methods: Open app/Http/Controllers/UrlController.php and define the methods for displaying the form, creating the short URL, and redirecting to the original URL.

    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use App\Models\Url;
    use Illuminate\Support\Str;
    
    class UrlController extends Controller
    {
        // Display the form for creating a new short URL
        public function index()
        {
            return view('url.index');
        }
    
        // Store a new short URL
        public function store(Request $request)
        {
            $request->validate([
                'original_url' => 'required|url'
            ]);
    
            $url = new Url();
            $url->original_url = $request->original_url;
            $url->short_url = Str::random(6);
            $url->save();
    
            return redirect()->route('url.show', $url->short_url);
        }
    
        // Redirect to the original URL
        public function show($short_url)
        {
            $url = Url::where('short_url', $short_url)->firstOrFail();
            return redirect($url->original_url);
        }
    }
    

Setting Up Routes

Next, we need to define the routes for our URL shortener.

  1. Open routes/web.php and add the following routes:

    use App\Http\Controllers\UrlController;
    
    Route::get('/', [UrlController::class, 'index'])->name('url.index');
    Route::post('/shorten', [UrlController::class, 'store'])->name('url.store');
    Route::get('/{short_url}', [UrlController::class, 'show'])->name('url.show');
    

Creating Views

We will create views to display the form for creating new short URLs and showing the shortened URL.

  1. Create a directory for views: Inside resources/views, create a folder named url.

  2. Create index.blade.php: This view will contain the form for submitting a new URL.

    <!-- resources/views/url/index.blade.php -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>URL Shortener</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    </head>
    <body>
        <div class="container mt-5">
            <h1 class="text-center">URL Shortener</h1>
            <form action="{{ route('url.store') }}" method="POST">
                @csrf
                <div class="form-group">
                    <label for="original_url">Enter URL:</label>
                    <input type="url" name="original_url" class="form-control" required>
                </div>
                <button type="submit" class="btn btn-primary">Shorten URL</button>
            </form>
        </div>
    </body>
    </html>
    
  3. Create show.blade.php: This view will display the shortened URL.

    <!-- resources/views/url/show.blade.php -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>URL Shortener</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    </head>
    <body>
        <div class="container mt-5">
            <h1 class="text-center">URL Shortener</h1>
            <p class="text-center">
                Your shortened URL is:
                <a href="{{ route('url.show', $url->short_url) }}">
                    {{ route('url.show', $url->short_url) }}
                </a>
            </p>
        </div>
    </body>
    </html>
    

Generating Short URLs

We use Laravel's Str::random() method to generate random strings for our short URLs. This method ensures that our URLs are unique and of the specified length.

In the store method of the UrlController, we generate a random string of six characters:

$url->short_url = Str::random(6);

Handling Redirections

The show method in the UrlController handles the redirection. It fetches the original URL from the database using the provided short URL and redirects the user to it.

public function show($short_url)
{
    $url = Url::where('short_url', $short_url)->firstOrFail();
    return redirect($url->original_url);
}

Implementing Custom Middleware

Middleware in Laravel can be used to handle various tasks, such as authentication, logging, or input validation. We can create custom middleware to log URL accesses.

  1. Generate middleware:

    php artisan make:middleware LogUrlAccess
    
  2. Define the middleware logic: Open app/Http/Middleware/LogUrlAccess.php and update the handle method:

    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Log;
    
    class LogUrlAccess
    {
        public function handle(Request $request, Closure $
    
    

next) { $short_url = $request->route('short_url'); Log::info('Short URL accessed:', ['short_url' => $short_url]); return $next($request); } }


3. **Register the middleware:** Open `app/Http/Kernel.php` and add the middleware to the `$routeMiddleware` array:

```php
protected $routeMiddleware = [
    // Other middleware...
    'log.url.access' => \App\Http\Middleware\LogUrlAccess::class,
];
  1. Apply the middleware to the route: Open routes/web.php and apply the middleware to the route that handles redirection:

    Route::get('/{short_url}', [UrlController::class, 'show'])
        ->name('url.show')
        ->middleware('log.url.access');
    

Testing Your Application

Testing is crucial to ensure your application works as expected. Laravel provides robust testing tools out of the box.

  1. Create a test for URL shortening: Open tests/Feature/UrlShortenerTest.php and write the following test:

    namespace Tests\Feature;
    
    use Illuminate\Foundation\Testing\RefreshDatabase;
    use Tests\TestCase;
    use App\Models\Url;
    
    class UrlShortenerTest extends TestCase
    {
        use RefreshDatabase;
    
        /** @test */
        public function it_can_shorten_a_url()
        {
            $response = $this->post('/shorten', [
                'original_url' => 'https://www.example.com'
            ]);
    
            $response->assertStatus(302);
            $this->assertDatabaseHas('urls', [
                'original_url' => 'https://www.example.com'
            ]);
        }
    
        /** @test */
        public function it_redirects_to_original_url()
        {
            $url = Url::create([
                'original_url' => 'https://www.example.com',
                'short_url' => 'abc123'
            ]);
    
            $response = $this->get('/abc123');
    
            $response->assertRedirect('https://www.example.com');
        }
    }
    
  2. Run the tests:

    php artisan test
    

    Ensure all tests pass to verify the functionality of your URL shortener.

Deploying the Application

Once your application is built and tested, it's time to deploy it. Here are the steps for deploying a Laravel application to a production server.

  1. Choose a hosting provider: Some popular options include AWS, DigitalOcean, and Heroku. For this tutorial, we'll use Laravel Forge, a service that simplifies deploying Laravel applications.

  2. Set up Laravel Forge:

    • Sign up for a Laravel Forge account.
    • Connect your server provider (e.g., DigitalOcean).
    • Create a new server and configure it with your domain.
  3. Deploy your application:

    • Link your Forge account to your GitHub repository containing the URL shortener project.
    • Configure the deployment script to run migrations and other necessary commands.
    • Deploy the application through the Forge dashboard.
  4. Set up environment variables: Ensure that your .env file on the server contains the correct database and application settings.

Conclusion

Building a URL shortener service with Laravel is a great way to learn about web development and the features of this powerful PHP framework. We covered the entire process, from setting up the project to deploying it, including:

  • Setting up a Laravel project
  • Configuring the database
  • Creating models, controllers, and views
  • Generating short URLs
  • Handling redirections
  • Implementing custom middleware
  • Testing the application
  • Deploying to a production server

With this knowledge, you can further enhance your URL shortener by adding features like user authentication, analytics, or custom URL aliases.