Skip to content
Can I Connect?

How Custom List Sharing Works

Your custom list is encoded entirely in the URL. No account, no server storage, no cookies. Here's how.

The URL Hash

When you add URLs to your custom list, they're compressed and stored in the URL fragment (the part after #). For example:

https://caniconnect.com/custom#NobwRAZghgNlQEYBsCWB7M...

The fragment is never sent to the server. It lives entirely in your browser. When you share the link, the recipient's browser decodes the list locally.

LZ-String Compression

Raw URL lists would create enormous share links. We use LZ-String compression to shrink the data:

1

Serialize

Your list of URLs is converted to a JSON array.

["https://aws.amazon.com","https://cloud.google.com"]
2

Compress

LZ-String compresses the JSON using a variant of the LZ algorithm optimized for strings. The output is typically 40-60% smaller than the original.

3

Encode

The compressed output is encoded as a URL-safe string using LZ-String's compressToEncodedURIComponent safe for use in URL fragments without further escaping.

Decoding works in reverse: decompress the hash → parse JSON → render the list. Everything happens in your browser.

Limitations

LimitValueWhy
Max URLs per list50Keeps the page responsive and avoids overwhelming the browser with concurrent requests.
Max URL length2,048 charsStandard URL length limit. Very long URLs inflate the share link disproportionately.
Share URL size limit~8,000 charsBrowsers and tools (Slack, Discord, Twitter) may truncate URLs longer than this. The progress bar on the custom page tracks your usage.
HTTPS/HTTP onlyn/aBrowsers can only fetch() HTTP(S) URLs. Other protocols (FTP, SSH, custom ports) are not supported.
Server probe rate limit10 req/min, 30 URLs/hr"Check from servers" uses SSRF-protected on-demand probes. Rate limits are per IP to prevent abuse.
No persistencen/aLists are not stored on a server. If you lose the URL, the list is gone. Bookmark it!

Privacy

The URL fragment (#...) is never sent to the server. Per RFC 3986 §3.5, the fragment identifier is resolved client-side only.

This means:

  • We never see which URLs are in your list
  • No list data appears in server logs or analytics
  • If you use "Check from servers", each URL is sent to the API individually, but the full list composition is never transmitted
  • If crowdsource is enabled, ping results are submitted per-URL (see Privacy)

Building Links Programmatically

You can generate custom list links from code using the lz-string library (available on npm for JS/TS, or in many languages):

JavaScript / Node.js
import { compressToEncodedURIComponent } from 'lz-string';

const urls = [
  'https://aws.amazon.com',
  'https://cloud.google.com',
  'https://status.github.com'
];

const hash = compressToEncodedURIComponent(JSON.stringify(urls));
const link = `https://caniconnect.com/custom#${hash}`;
console.log(link);
Python
import lzstring, json

urls = [
    "https://aws.amazon.com",
    "https://cloud.google.com",
    "https://status.github.com"
]

lz = lzstring.LZString()
hash = lz.compressToEncodedURIComponent(json.dumps(urls))
print(f"https://caniconnect.com/custom#{hash}")

LZ-String has implementations in JavaScript, Python, C#, Java, Go, Ruby, and more. The encoding format is cross-compatible. A link generated in Python works in the browser and vice versa.