shrtnr 2.0.0 copy "shrtnr: ^2.0.0" to clipboard
shrtnr: ^2.0.0 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(id, {url?, label?, expiresAt?}) Update URL, label, or expiry
disable(id) Stop redirecting
enable(id) Resume redirecting
delete(id) Permanently delete
analytics(id, {range?}) Click breakdown by country, device, referrer, etc.
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: '7d');

// Full analytics for the last 30 days
final stats = await client.links.analytics(link.id, range: '30d');
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(id, {name?, description?, icon?, accent?}) Update metadata
delete(id) Permanently delete
archive(id) Hide from default listing
unarchive(id) Restore an archived bundle
analytics(id, {range?}) Combined click analytics
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: '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: '7d');
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
  • DateClickCount, SlugClickCount
  • DeletedResult, AddedResult, RemovedResult

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
160
points
464
downloads

Documentation

API reference

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

Apache-2.0 (license)

Dependencies

http, meta

More

Packages that depend on shrtnr