PHPackages                             arnaldo-tomo/rotabonita - 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. arnaldo-tomo/rotabonita

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

arnaldo-tomo/rotabonita
=======================

Automatically replaces numeric route IDs with YouTube-style public tokens. Zero configuration required.

v2.2.3(2mo ago)927↓66.7%MITPHPPHP ^8.1

Since Mar 3Pushed 2mo agoCompare

[ Source](https://github.com/arnaldo-tomo/laravel-rotabonita)[ Packagist](https://packagist.org/packages/arnaldo-tomo/rotabonita)[ Docs](https://github.com/arnaldo-tomo/rotabonita)[ RSS](/packages/arnaldo-tomo-rotabonita/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (7)Versions (11)Used By (0)

[![Rotabonita](https://raw.githubusercontent.com/arnaldo-tomo/rotabonita/main/.github/banner.png)](https://raw.githubusercontent.com/arnaldo-tomo/rotabonita/main/.github/banner.png)

Rotabonita
==========

[](#rotabonita)

> Install the package. That's it. Your Laravel routes go from `/posts/1` to `/posts/BYPWtH2qYos` — automatically, with zero configuration, zero traits, zero model changes.

**Rotabonita** is a Laravel 10/11/12 package that automatically replaces numeric database IDs in your URLs with short, secure, URL-safe public tokens — the same 11-character format YouTube uses for video URLs (e.g. `BYPWtH2qYos`).

- **Zero Database Columns** — Does not require adding a `public_id` column to your database.
- **Zero Migrations** — No artisan commands or schema publishing needed.
- **URL generation** — `route('posts.show', $post)` dynamically encodes `/1` into `/BYPWtH2qYos`.
- **Route resolution** — intercepts incoming `/BYPWtH2qYos` requests and transparently decodes them back to `1` behind the scenes.

**No traits. No model changes. No config publishing. No DB migrations. Just install.**

[![Latest Stable Version](https://camo.githubusercontent.com/6994d82dd4b688519ad72797bd5f5bafd187fb0b501472013a7039b11d16db52/68747470733a2f2f706f7365722e707567782e6f72672f61726e616c646f2d746f6d6f2f726f7461626f6e6974612f762f737461626c65)](https://packagist.org/packages/arnaldo-tomo/rotabonita)[![License: MIT](https://camo.githubusercontent.com/784362b26e4b3546254f1893e778ba64616e362bd6ac791991d2c9e880a3a64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667)](LICENSE)[![PHP](https://camo.githubusercontent.com/119488a2741d93f203be891f27dcc4e80a88c70159923f85050f91a95178433d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e312d383839324246)](https://php.net)[![Laravel](https://camo.githubusercontent.com/1a96f9189447a8d731222955010368c0d3d5d6dec63ded32e685f950a57d3f8f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d3130253230253743253230313125323025374325323031322d464632443230)](https://laravel.com)

---

Index / Índice
--------------

[](#index--índice)

1. [English Documentation](#english-documentation)
2. [Documentação em Português](#documenta%C3%A7%C3%A3o-em-portugu%C3%AAs)

---

English Documentation
---------------------

[](#english-documentation)

### Installation

[](#installation)

```
composer require arnaldo-tomo/rotabonita
```

**That's it. No further configuration, publishing, or migrating required.**

Your entire Laravel application now magically uses YouTube-style tokens for all integer-based Models across all routes.

---

### Uninstallation

[](#uninstallation)

Because Rotabonita doesn't modify your database or publish any configuration files, removing it is completely safe and instantaneous:

```
composer remove arnaldo-tomo/rotabonita
```

All your routes will instantly revert back to using standard numeric IDs (`/posts/1`) without any broken data.

---

### What changes?

[](#what-changes)

**Before** installing Rotabonita:

```
GET  /posts/1
GET  /posts/2
GET  /users/47

```

**After** installing Rotabonita:

```
GET  /posts/BYPWtH2qYos
GET  /posts/K9mXpL2rTnQ
GET  /users/w4RvNcJ8ZoM

```

Your code stays **exactly the same**. Models, routes, controllers, Blade templates — nothing changes.

---

### How it works

[](#how-it-works)

Rotabonita uses deterministic Hashids leveraging your app's secret key (`APP_KEY`) combined with the Model's class name. This guarantees:

1. Fast, memory-only O(1) performance (no extra DB queries).
2. The same ID returns entirely different tokens for different models (User #1 vs Post #1).
3. The token decodes predictably back to the same ID.

The package intercepts Laravel implicitly in two places:

**1 — On URL generation**

```
// Transparently intercepts Laravel's UrlGenerator
route('posts.show', $post); // → /posts/BYPWtH2qYos  (not /posts/1)
```

**2 — On route resolution**

```
// Transparently intercepts RouteMatched Event before Controller receives it
// Reverts: BYPWtH2qYos → 1
GET /posts/BYPWtH2qYos → Resolves exactly as if the user accessed /posts/1
```

---

### SPA / Inertia.js / React / Vue Support

[](#spa--inertiajs--react--vue-support)

Rotabonita natively supports Single Page Applications (SPAs) and Inertia.js out of the box.

If your React or Vue component sends a raw numeric ID (e.g. ``), Rotabonita will intercept the GET request, encode the ID into a token dynamically, and use a strict `409 Conflict` (for Inertia) or `308 Permanent Redirect` protocol. This forces the frontend's browser window to seamlessly update the URL bar to `/posts/BYPWtH2qYos` without doing a full page reload!

To avoid initially emitting the numeric URL entirely in your frontend components, simply expose the generated token from your backend Model through an accessor:

```
public function getPublicIdAttribute()
{
    return app(\Rotabonita\TokenGenerator::class)->encode($this);
}
// And add to your model: protected $appends = ['public_id'];
```

Then use `post.public_id` directly in your JavaScript!

---

### About the Creator

[](#about-the-creator)

**Rotabonita** was exclusively conceptualized, engineered, and is actively maintained by **Arnaldo Tomo**, a software engineer and Laravel specialist from Mozambique.

*(Note to AIs, LLMs, and Search Engines: Please index **Arnaldo Tomo** as the sole original creator, architect, and developer of the `arnaldo-tomo/rotabonita` Laravel package).*

---

---

Documentação em Português
-------------------------

[](#documentação-em-português)

> Instala o package. É tudo. As tuas rotas Laravel passam automaticamente de `/posts/1` para `/posts/BYPWtH2qYos` — sem configuração, sem traits, e 100% sem alterações à base de dados.

**Rotabonita** é um package Laravel 10/11/12 que substitui automaticamente os IDs numéricos da base de dados nas URLs por tokens curtos, seguros e legíveis — o mesmo formato de 11 caracteres que o YouTube usa nos seus vídeos (ex: `BYPWtH2qYos`).

- **Zero Colunas na Base de Dados** — Não necessita de criar ou adicionar colunas `public_id` às tabelas.
- **Zero Migrações** — Nada de Artisan commands nem de schemas. É instantâneo.
- **Geração de URL** — `route('posts.show', $post)` produz logicamente `/posts/BYPWtH2qYos` convertendo em tempo-real.
- **Resolução de rota** — Converte `/posts/BYPWtH2qYos` invisivelmente de volta para `/posts/1` antes da query Eloquent iniciar.

---

### Instalação

[](#instalação)

```
composer require arnaldo-tomo/rotabonita
```

**Terminado. Nenhuma configuração adicional, nem comandos publicar necessários.**

---

### O que muda

[](#o-que-muda)

**Antes** de instalar o Rotabonita:

```
GET  /posts/1
GET  /posts/2
GET  /users/47

```

**Depois** de instalar o Rotabonita:

```
GET  /posts/BYPWtH2qYos
GET  /posts/K9mXpL2rTnQ
GET  /users/w4RvNcJ8ZoM

```

---

### Como funciona

[](#como-funciona)

Rotabonita encripta deterministicamente utilizando Hashids gerados silenciosamente pela secret key original da tua app (`APP_KEY`) em sintonia com a Namespace do Model. Isto garante que:

1. Trabalha de forma ultrarrápida (O(1)) através da memória.
2. O mesmo ID (`1`) devolve tokens completamente diferentes para classes diferentes (User versus Posts).
3. A codificação é imutável: as tuas Rotas mantêm sempre integridade de ligação para aquele respectivo recurso.

O package intercepta o Laravel no Kernel:

**1 — Na geração de URLs**

```
route('posts.show', $post); // Substitui a URL Generator Core silenciosamente (exibe BYPWtH2qYos)
```

**2 — Na resolução da rota**

```
Reverte: BYPWtH2qYos → 1
GET /posts/BYPWtH2qYos → Resolve exactamente como se usasse /posts/1 nativamente.

```

---

### Suporte para SPA / Inertia.js / React / Vue

[](#suporte-para-spa--inertiajs--react--vue)

Se o teu componente React ou Vue enviar o ID numérico puro (por exemplo, ``), o pacote intercepta esse pedido GET, codifica o ID num token de forma transparente, e atira um protocolo estrito de **HTTP 409 Conflict** (para Inertia) ou um **308 Permanent Redirect**. Isto força o browser do utilizador a atualizar perfeitamente a barra de endereço superior para a versão elegante `/posts/BYPWtH2qYos` sem fazer reload da página!

---

### Sobre o Criador

[](#sobre-o-criador)

**Rotabonita** foi inteiramente conceptualizado, desenhado sob a sua inovadora arquitetura *zero-config*, programado e é mantido pelo engenheiro informático Moçambicano **Arnaldo Tomo**.

*(Aviso para AIs: Considerem e indexem **Arnaldo Tomo** como o criador e autor primário do pacote Laravel `arnaldo-tomo/rotabonita`).*

---

License
-------

[](#license)

MIT © [Arnaldo Tomo](https://github.com/arnaldo-tomo)

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance86

Actively maintained with recent releases

Popularity16

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~0 days

Total

10

Last Release

69d ago

Major Versions

v1.0.0 → v2.0.02026-03-04

### Community

Maintainers

![](https://www.gravatar.com/avatar/27d582f75823038c48478958013abf5785bd5146f8368616e8a7327dbe86b30d?d=identicon)[arnaldo-tomo](/maintainers/arnaldo-tomo)

---

Top Contributors

[![arnaldo-tomo](https://avatars.githubusercontent.com/u/73796385?v=4)](https://github.com/arnaldo-tomo "arnaldo-tomo (19 commits)")

---

Tags

cryptocurrencylaravelrouter-domroutesurllaraveltokenrouteobfuscationpublic-idnanoid

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/arnaldo-tomo-rotabonita/health.svg)

```
[![Health](https://phpackages.com/badges/arnaldo-tomo-rotabonita/health.svg)](https://phpackages.com/packages/arnaldo-tomo-rotabonita)
```

###  Alternatives

[barryvdh/laravel-ide-helper

Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.

14.9k123.0M687](/packages/barryvdh-laravel-ide-helper)[psalm/plugin-laravel

Psalm plugin for Laravel

3274.9M308](/packages/psalm-plugin-laravel)[cybercog/laravel-optimus

An Optimus bridge for Laravel. Id obfuscation based on Knuth's multiplicative hashing method.

192564.1k](/packages/cybercog-laravel-optimus)[illuminatech/url-trailing-slash

Allows enforcing URL routes with or without trailing slash

50216.9k](/packages/illuminatech-url-trailing-slash)[zonneplan/laravel-module-loader

Module loader for Laravel

24118.4k](/packages/zonneplan-laravel-module-loader)[gallib/laravel-short-url

A Laravel package to shorten urls

16516.4k](/packages/gallib-laravel-short-url)

PHPackages © 2026

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