Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cuttly Laravel Package

slvler/cuttly

A Laravel/PHP wrapper for the Cutt.ly URL shortener API. It lets you create and manage short links, use branded domains, and retrieve click analytics from your application, with straightforward configuration and a clean, simple integration for Laravel projects. Ideal for adding link shortening to La...

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install — composer require slvler/cuttly. Laravel package auto-discovery registers the service provider and Cuttly facade; no manual registration needed on Laravel 8+.
  2. Publish config — php artisan vendor:publish --tag=cuttly-config (creates config/cuttly.php). If the tag isn't registered, check php artisan vendor:publish and pick the CuttlyServiceProvider entry.
  3. Set your API key — add CUTTLY_API_KEY=... to .env (get a key from the Cutt.ly dashboard). The config file reads from env('CUTTLY_API_KEY'); verify the exact key name in the published config, because wrappers in this genre sometimes use CUTTLY_KEY or similar and you'll silently hit an auth error otherwise.
  4. First use case — shorten a URL and redirect/store it:
use Slvler\Cuttly\Facades\Cuttly;

$response = Cuttly::shorten('https://example.com/some/long/path');
// inspect the returned array/object per the README — Cutt.ly returns
// payloads like ['url' => ['status' => 7, 'shortLink' => '...']]

Where to look first: the repo README (it's the only real docs), then src/ — it's a thin wrapper, so the facade class and its underlying client show you every available method (shorten, stats, edit, delete are the Cutt.ly API surface). If a method you need isn't exposed, you'll extend it or call the HTTP client directly.

Implementation Patterns

Wrap the facade in your own service. Don't scatter Cuttly:: calls through controllers — inject a UrlShortener class that returns a normalized DTO (shortUrl, status, raw). That gives you a single seam to swap providers later and a clean place to handle the array-shaped responses.

Persist the mapping, not just the string. Store original_url, short_url, provider_ref, created_at on your model. You'll want the original to rebuild links, detect duplicates, and reconcile if Cutt.ly changes a slug.

Idempotency for user-submitted links. Check your DB for an existing shortened row before calling the API — cheap optimization and it keeps you well under rate limits when a user pastes the same URL twice.

Queue it for bulk work. Shortening N links in a request will hit Cutt.ly's rate limits and slow page loads. Dispatch a job per URL (or small batches) and update the model on completion. Add $tries/backoff on the job since the wrapper typically doesn't retry for you.

Custom domain / custom slug params. Cutt.ly supports custom_domain and slug on the shorten call. Pass them through at construction time rather than post-processing the response — the API applies them server-side and errors if the slug is taken, which you need to surface to the user.

Stats integration. If you render click counts, cache Cuttly::stats($id) results for a few minutes and refresh via a scheduled command — otherwise you'll burn quota on dashboard refreshes.

Testing. Bind a fake or Http::fake() the underlying endpoint in tests. Cutt.ly returns HTTP 200 with a JSON status field even on some failures, so fake realistic payloads (both success and status != 7) to exercise your error branch.

Gotchas and Tips

  • Cutt.ly returns 200 on logical errors. The API signals failures via a status code inside the body, not just HTTP status. Always inspect the status/errors field before treating a response as success — a naive if ($response) will pass bad data through.
  • URL must include the scheme. example.com will fail or produce a broken link; validate with filter_var($url, FILTER_VALIDATE_URL) before calling.
  • Env caching bites. Run php artisan config:clear after editing .env; a cached config with a stale/missing key is the #1 "it worked yesterday" cause.
  • Response shape is an array of nested arrays. Reach into ['url']['shortLink'] defensively with data_get() and handle missing keys — the package doesn't always normalize.
  • No built-in retry or rate-limit handling. Wrap calls in retry() from Laravel's helpers with a short backoff, and catch connection exceptions explicitly.
  • Small package, low maintenance. With ~40 stars and dependents near zero, expect the README to be the full documentation and issue responses to be slow. Treat it as a starting point, not a black box — it's thin enough to fork or inline if you need a method it doesn't expose.
  • Extension points: the service container binding is where you'd override the client ($this->app->bind(...) in a service provider) if you need custom HTTP options, timeouts, or a different base URL for testing. Add a timeout to the Guzzle client — the default can hang your request thread.
  • Custom domains and permissioning: team accounts and custom domains require the key to have access; a valid key can still return a permission error for domain-specific operations. Verify on the Cutt.ly dashboard before debugging your code.
  • Locking to a version. Last release was Nov 2024; pin ^1.x (or the current major) and check the changelog before minor bumps, since response shapes are the most likely thing to shift in a wrapper this small.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect