shrtnr 2.1.3 copy "shrtnr: ^2.1.3" to clipboard
shrtnr: ^2.1.3 copied to clipboard

Dart client for the shrtnr URL shortener API. Create short links, manage custom slugs, and read click analytics.

shrtnr #

Dart SDK for shrtnr, a self-hosted URL shortener on Cloudflare Workers. Create short links, manage slugs, and read click analytics.

pub.dev license

Install #

dart pub add shrtnr

Quick start #

import 'package:shrtnr/shrtnr.dart';

final client = ShrtnrClient(
  baseUrl: 'https://your-shrtnr.example.com',
  apiKey: 'sk_your_api_key',
);

final link = await client.links.create(url: 'https://example.com/very-long-path');
print(link.slugs.first.slug); // 'a3x9'

client.close();

Configuration #

ShrtnrClient(
  baseUrl: 'https://your-shrtnr.example.com', // required
  apiKey: 'sk_...',                            // required; from the admin dashboard
  httpClient: customHttpClient,                // optional; inject a custom http.Client
)

The httpClient parameter accepts any http.Client. Pass a custom implementation for test mocking or custom TLS configuration. When omitted, a new http.Client is created and closed by client.close().

Resources #

Method Description
get(id, {range?}) Get a link with click count
list({owner?, range?}) List all links
create({url, label?, slugLength?, expiresAt?, allowDuplicate?}) Create a short link
update(link) Update URL, label, or expiry (pass a Link from copyWith)
disable(id) Stop redirecting
enable(id) Resume redirecting
delete(id) Permanently delete
analytics(id, {range?}) Click breakdown by country, device, referrer, etc.
breakdown(id, {dimension, range?, offset?, limit?}) Page through the countries, sources (referrers) or domains (referrer_hosts) breakdown
timeline(id, {range?}) Click counts bucketed over time
qr(id, {slug?, size?}) QR code as SVG string
bundles(id) Bundles this link belongs to
// Shorten a URL
final link = await client.links.create(url: 'https://example.com', label: 'Landing page');

// Get a 7-day click count
final fresh = await client.links.get(link.id, range: TimelineRange.last7d);

// Full analytics for the last 30 days
final stats = await client.links.analytics(link.id, range: TimelineRange.last30d);
print('${stats.totalClicks} clicks, ${stats.numCountries} countries');

Slugs (client.slugs) #

Method Description
lookup(slug) Find a link by slug
add(linkId, slug) Add a custom slug
disable(linkId, slug) Disable a slug
enable(linkId, slug) Re-enable a slug
remove(linkId, slug) Remove a slug
// Add a campaign slug then disable it when the campaign ends
await client.slugs.add(link.id, 'spring-sale');
await client.slugs.disable(link.id, 'spring-sale');

// Look up a link by its slug
final found = await client.slugs.lookup('spring-sale');

Bundles (client.bundles) #

Groups of related links with combined analytics.

Method Description
get(id, {range?}) Get a bundle with click summary
list({archived?, range?}) List bundles
create({name, description?, icon?, accent?}) Create a bundle
update(bundle) Update metadata (pass a Bundle from copyWith)
delete(id) Permanently delete
archive(id) Hide from default listing
unarchive(id) Restore an archived bundle
analytics(id, {range?}) Combined click analytics
breakdown(id, {dimension, range?, offset?, limit?}) Page through the countries, sources (referrers) or domains (referrer_hosts) breakdown
links(id) List links in the bundle
addLink(id, linkId) Add a link
removeLink(id, linkId) Remove a link
// Create a bundle and add links to it
final bundle = await client.bundles.create(name: 'Spring 2026', accent: BundleAccent.green);
await client.bundles.addLink(bundle.id, linkA.id);
await client.bundles.addLink(bundle.id, linkB.id);

// Combined analytics for the last 7 days
final stats = await client.bundles.analytics(bundle.id, range: TimelineRange.last7d);
print(stats.totalClicks);

Models #

All model fields use camelCase. The SDK maps snake_case JSON from the wire automatically inside each fromJson factory.

Key types exported from package:shrtnr/shrtnr.dart:

  • Link, Slug, Bundle, BundleWithSummary, BundleTopLink
  • ClickStats, TimelineData, TimelineBucket, TimelineSummary, NameCount
  • DateCount, SlugCount
  • DeletedResult, AddedResult, RemovedResult
  • Enums: TimelineRange, BundleAccent, BreakdownDimension, BundleArchivedFilter

Timestamp fields (createdAt, expiresAt, disabledAt, archivedAt, updatedAt) are plain int Unix seconds, matching the wire format exactly.

Errors #

Every 4xx/5xx response throws ShrtnrError. Network failures also throw ShrtnrError with status: 0.

import 'package:shrtnr/shrtnr.dart';

try {
  await client.links.get(99999);
} on ShrtnrError catch (err) {
  print(err.status);         // 404
  print(err.serverMessage);  // 'not found'
  print(err);                // 'ShrtnrError(HTTP 404): not found'
}

See also #

Attribution #

shrtnr is developed and maintained by Oddbit.

If you publish a fork or derivative work, retain the license and notice files, preserve applicable copyright and attribution notices, and clearly indicate that your version has been modified.

1
likes
0
points
257
downloads

Publisher

verified publisheroddbit.id

Weekly Downloads

Dart client for the shrtnr URL shortener API. Create short links, manage custom slugs, and read click analytics.

Homepage
Repository (GitHub)
View/report issues

Topics

#url-shortener #short-url #link-management #analytics

License

unknown (license)

Dependencies

http, meta

More

Packages that depend on shrtnr