Relay SMS Platform
Best Practices

5. URL Shortening

Always use short URLs in templates to save characters and reduce SMS segments.

Impact of Long URLs

Long URLs significantly increase message length:

TypeScriptCode
import { getTemplate, renderTemplate } from '@relay-works/templates'; // ❌ Long URL - May require 2 segments const longResult = renderTemplate(getTemplate('password-reset'), { company: 'Acme', url: 'https://mystore.com/account/reset-password?token=abc123&utm_source=sms&utm_medium=text', minutes: 15 }); console.log(longResult.segments); // 2 segments = $0.04 // ✅ Short URL - Single segment const shortResult = renderTemplate(getTemplate('password-reset'), { company: 'Acme', url: 'https://relay.link/rst-x7k', minutes: 15 }); console.log(shortResult.segments); // 1 segment = $0.02

URL Shortening Services

Bitly

  • Free tier available
  • Custom branded domains
  • Analytics included
TypeScriptCode
import { BitlyClient } from 'bitly'; const bitly = new BitlyClient(process.env.BITLY_ACCESS_TOKEN!); async function shortenUrl(longUrl: string): Promise<string> { const result = await bitly.shorten(longUrl); return result.link; // https://bit.ly/abc123 }

TinyURL

  • Simple and free
  • No account required
  • Basic functionality
TypeScriptCode
async function shortenWithTinyUrl(longUrl: string): Promise<string> { const response = await fetch( `https://tinyurl.com/api-create.php?url=${encodeURIComponent(longUrl)}` ); return await response.text(); // https://tinyurl.com/abc123 }

Custom Domain (Recommended)

  • Best for branding
  • Full control
  • Professional appearance
TypeScriptCode
// Using a custom short domain like acme.link const shortUrl = `https://acme.link/${generateShortCode()}`;

URL Validation

Templates enforce a 50-character URL limit:

TypeScriptCode
const validation = validateTemplateData(template, { company: 'Acme', url: 'https://very-long-domain-name.com/extremely/long/path/...', // Too long! minutes: 15 }); if (!validation.valid) { console.log(validation.errors[0].message); // "Must be 50 characters or less" console.log(validation.errors[0].suggestion); // "Use a URL shortening service" }

Implementation Example

TypeScriptCode
import { getTemplate, renderTemplate } from '@relay-works/templates'; async function sendPasswordReset(email: string, resetToken: string) { // Create long URL const longUrl = `https://myapp.com/reset-password?token=${resetToken}&email=${email}`; // Shorten it const shortUrl = await shortenUrl(longUrl); // Use in template const result = renderTemplate(getTemplate('password-reset'), { company: 'Acme', url: shortUrl, minutes: 15 }); // Send await relay.messages.send({ to: getUserPhoneNumber(email), message: result.text }); }

URL Shortening Best Practices

  1. Always shorten URLs over 30 characters

    TypeScriptCode
    if (url.length > 30) { url = await shortenUrl(url); }
  2. Use custom domains for branding

    TypeScriptCode
    // ✅ Good - branded url: 'https://acme.link/order-123' // ❌ Generic url: 'https://bit.ly/abc123'
  3. Remove tracking parameters

    TypeScriptCode
    // ❌ Don't do this url: 'https://acme.link/x7k?utm_source=sms&utm_medium=text' // ✅ Do this - track server-side instead url: 'https://acme.link/x7k'
  4. Test shortened URLs

    TypeScriptCode
    // Verify shortened URL works const response = await fetch(shortUrl); if (!response.ok) { throw new Error('Shortened URL is invalid'); }
  5. Cache shortened URLs

    TypeScriptCode
    const urlCache = new Map<string, string>(); async function getCachedShortUrl(longUrl: string): Promise<string> { if (urlCache.has(longUrl)) { return urlCache.get(longUrl)!; } const shortUrl = await shortenUrl(longUrl); urlCache.set(longUrl, shortUrl); return shortUrl; }

Character Savings

Example savings with URL shortening:

URL TypeLengthSegmentsCost
Long URL (80 chars)160+2$0.04
Short URL (20 chars)1001$0.02
Savings60 chars1 segment50%

Next Steps:

Last modified on