PHPackages                             fkrzski/laravel-canonical - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. fkrzski/laravel-canonical

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

fkrzski/laravel-canonical
=========================

Laravel package for managing canonical URLs and preventing duplicate content

1.4.0(3mo ago)289[1 PRs](https://github.com/fkrzski/laravel-canonical/pulls)MITPHPPHP ^8.4 | ^8.5CI passing

Since Oct 20Pushed 3w ago1 watchersCompare

[ Source](https://github.com/fkrzski/laravel-canonical)[ Packagist](https://packagist.org/packages/fkrzski/laravel-canonical)[ Docs](https://github.com/fkrzski/laravel-canonical)[ GitHub Sponsors](https://github.com/fkrzski)[ RSS](/packages/fkrzski-laravel-canonical/feed)WikiDiscussions master Synced today

READMEChangelog (5)Dependencies (24)Versions (8)Used By (0)

Laravel Canonical URLs
======================

[](#laravel-canonical-urls)

[![Latest Version on Packagist](https://camo.githubusercontent.com/90e572b06abef4a496929213d1c473d69bf0c9fa155f2592f7fd7001a5746660/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f666b727a736b692f6c61726176656c2d63616e6f6e6963616c2e7376673f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/fkrzski/laravel-canonical)[![Tests](https://camo.githubusercontent.com/4117064a6225ccdf599836f460a3387beca29d3215a9b2e8c052457c527ce723/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f666b727a736b692f6c61726176656c2d63616e6f6e6963616c2f74657374732e796d6c3f6272616e63683d6d6173746572266c6162656c3d7465737473267374796c653d666f722d7468652d6261646765)](https://github.com/fkrzski/laravel-canonical/actions/workflows/tests.yml)[![Total Downloads](https://camo.githubusercontent.com/8cb1dab3d79e4a33078707b1ef7029e1b94660164a841fbdc1d619f0b4468260/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f666b727a736b692f6c61726176656c2d63616e6f6e6963616c2e7376673f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/fkrzski/laravel-canonical)

A lightweight Laravel package for generating canonical URLs to prevent duplicate content issues and improve SEO. Automatically normalizes URLs by removing trailing slashes while preserving query parameters.

Version Compatibility
---------------------

[](#version-compatibility)

Package VersionPHP VersionLaravel Version1.4.x+8.4+12.x, 13.x1.3.x+8.4+11.x, 12.x1.0.x - 1.2.x8.3+11.x, 12.xInstallation
------------

[](#installation)

Install via Composer:

```
composer require fkrzski/laravel-canonical
```

The package will auto-register via Laravel's package discovery.

Configuration
-------------

[](#configuration)

Publish the configuration file (optional):

```
php artisan vendor:publish --tag="canonical-config"
```

Set your canonical domain in `.env`:

```
CANONICAL_DOMAIN=https://example.com
```

If not set, it falls back to `APP_URL`.

### Trailing Slash Configuration

[](#trailing-slash-configuration)

**@since 1.1.0**

Control whether trailing slashes are removed from canonical URLs:

```
# Remove trailing slashes (default behavior)
CANONICAL_TRIM_TRAILING_SLASH=true

# Preserve trailing slashes
CANONICAL_TRIM_TRAILING_SLASH=false
```

When set to `true` (default), URLs are normalized by removing trailing slashes. When set to `false`, the original URL format is preserved.

Usage
-----

[](#usage)

### Blade Components

[](#blade-components)

**@since 1.2.0**

The package provides three convenient ways to add canonical link tags in your Blade templates:

#### 1. Using Blade Component

[](#1-using-blade-component)

```

    {{-- Use current request URL --}}

    {{-- Specify custom path --}}

    {{-- Use dynamic path --}}

```

#### 2. Using Helper Function

[](#2-using-helper-function)

The `canonical()` helper provides a hybrid approach - it can return either the generator instance or a URL string:

```

    {{-- Direct URL generation --}}

    {{-- Fluent usage (without arguments returns generator) --}}

    {{-- Use current request URL --}}

    {{-- Also works in PHP code --}}
    @php
        $url = canonical('/products/item'); // Returns: "https://example.com/products/item"
        $generator = canonical(); // Returns: CanonicalUrlGeneratorInterface instance
    @endphp

```

#### 3. Using Blade Directive

[](#3-using-blade-directive)

```

    {{-- Use current request URL --}}
    @canonical

    {{-- Specify custom path --}}
    @canonical('/products/item')

    {{-- Use variable --}}
    @canonical($canonicalPath)

```

#### All Three Methods Generate:

[](#all-three-methods-generate)

```

```

### In Blade Templates (Facade)

[](#in-blade-templates-facade)

Generate canonical URLs in your views using the Facade:

```

```

### Generate for Specific Paths

[](#generate-for-specific-paths)

```
use Fkrzski\LaravelCanonical\Facades\Canonical;

// Current request URI
Canonical::generate(); // https://example.com/blog/post

// Override with a custom path
Canonical::generate('/products/item'); // https://example.com/products/item

// Current request with query parameters (preserved)
// Request: /search?q=laravel&page=2
Canonical::generate(); // https://example.com/search?q=laravel&page=2

// Override path even when on different URL
// Current: /old-url, Generate: /new-canonical-url
Canonical::generate('/new-canonical-url'); // https://example.com/new-canonical-url
```

### URL Normalization

[](#url-normalization)

**With `CANONICAL_TRIM_TRAILING_SLASH=true` (default):**

- Removes trailing slashes: `/blog/` → `/blog`
- Preserves query parameters: `/search?q=test` stays intact
- Normalizes root URL: `/` → `https://example.com`

**With `CANONICAL_TRIM_TRAILING_SLASH=false` (@since 1.1.0):**

- Preserves trailing slashes: `/blog/` → `/blog/`
- Maintains original URL structure while still normalizing the domain
- Useful when your application treats `/blog` and `/blog/` as different routes

Use Cases
---------

[](#use-cases)

**Prevent duplicate content penalties:**

```
{{-- Both /blog and /blog/ point to same canonical --}}

```

**Multi-domain environments:**

```
// config/canonical.php
return [
    'domain' => env('CANONICAL_DOMAIN', config('app.url')),
];
```

**Preserve URL structure (@since 1.1.0):**

```
# When your app treats /page and /page/ differently
CANONICAL_TRIM_TRAILING_SLASH=false
```

```
{{-- /blog/ stays as /blog/ --}}

```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Filip Krzyżanowski](https://github.com/fkrzski)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance88

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 89.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~37 days

Total

5

Last Release

106d ago

PHP version history (2 changes)1.0.0PHP ^8.3

1.3.0PHP ^8.4 | ^8.5

### Community

Maintainers

![](https://www.gravatar.com/avatar/accf44fd0ffa5349a96edefe2daf51dc4475af31a01611acade1d44b35341d61?d=identicon)[fkrzski](/maintainers/fkrzski)

---

Top Contributors

[![fkrzski](https://avatars.githubusercontent.com/u/75097934?v=4)](https://github.com/fkrzski "fkrzski (42 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (4 commits)")[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (1 commits)")

---

Tags

canonicallaravelphpseoseotoolsphplaravelseocanonicalfkrzskilaravel-canonical

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/fkrzski-laravel-canonical/health.svg)

```
[![Health](https://phpackages.com/badges/fkrzski-laravel-canonical/health.svg)](https://phpackages.com/packages/fkrzski-laravel-canonical)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[renatomarinho/laravel-page-speed

Laravel Page Speed

2.5k1.7M11](/packages/renatomarinho-laravel-page-speed)[vinkius-labs/laravel-page-speed

Laravel Page Speed

2.5k12.5k1](/packages/vinkius-labs-laravel-page-speed)[bezhansalleh/filament-google-analytics

Google Analytics integration for FilamentPHP

211189.7k8](/packages/bezhansalleh-filament-google-analytics)[emargareten/inertia-modal

Inertia Modal is a Laravel package that lets you implement backend-driven modal dialogs for Inertia apps.

90142.9k](/packages/emargareten-inertia-modal)[wearepixel/laravel-cart

A cart implementation for Laravel

1374.8k](/packages/wearepixel-laravel-cart)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
