Skip to content

feat: implement device-based routing for short links#340

Merged
piffio merged 5 commits intomainfrom
feat/108-device-based-routing
Apr 27, 2026
Merged

feat: implement device-based routing for short links#340
piffio merged 5 commits intomainfrom
feat/108-device-based-routing

Conversation

@piffio
Copy link
Copy Markdown
Owner

@piffio piffio commented Apr 27, 2026

Add ability to set different destination URLs for iOS, Android, and Desktop devices. Users on Business and Unlimited tiers can configure device-specific redirects that automatically route visitors based on their device type.

Backend changes:

  • Add device detection module (src/utils/device.rs) with User-Agent parsing
  • Add device URL columns (ios_url, android_url, desktop_url) to links table
  • Update Link and LinkMapping models with device URL fields
  • Integrate device detection into redirect handler for automatic routing
  • Add tier gating for device routing (Business+ only)
  • Update all repository queries to include device URL fields
  • Fix usage API to return allow_device_routing flag

Frontend changes:

  • Add device routing UI to LinkModal with collapsible section
  • Show device-specific URL inputs (iOS, Android, Desktop) with icons
  • Display upgrade CTA for Free/Pro tiers
  • Update TypeScript API types with device URL fields

The feature is backward compatible - existing links continue to work normally, falling back to the default destination URL when device-specific URLs are not set.

Closes #108

Add ability to set different destination URLs for iOS, Android, and Desktop devices. Users on Business and Unlimited tiers can configure device-specific redirects that automatically route visitors based on their device type.

Backend changes:
- Add device detection module (src/utils/device.rs) with User-Agent parsing
- Add device URL columns (ios_url, android_url, desktop_url) to links table
- Update Link and LinkMapping models with device URL fields
- Integrate device detection into redirect handler for automatic routing
- Add tier gating for device routing (Business+ only)
- Update all repository queries to include device URL fields
- Fix usage API to return allow_device_routing flag

Frontend changes:
- Add device routing UI to LinkModal with collapsible section
- Show device-specific URL inputs (iOS, Android, Desktop) with icons
- Display upgrade CTA for Free/Pro tiers
- Update TypeScript API types with device URL fields

The feature is backward compatible - existing links continue to work normally, falling back to the default destination URL when device-specific URLs are not set.
@github-actions
Copy link
Copy Markdown

🚀 Ephemeral Environment Deployed (Unified Worker)

Application: https://rushomon-pr-340.piffio.workers.dev

This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly).

This environment will be automatically cleaned up when the PR is closed.

Worker: rushomon-pr-340


💡 Tip: To skip preview deployment, add the skip-preview label to this PR.

…ange

Previously, KV sync only occurred when link status changed, causing device routing
to fail when editing a link to add device-specific URLs. The redirect handler reads
from KV, so stale data caused fallback to default destination URL.

Now KV syncs whenever any LinkMapping field changes:
- status
- destination_url
- ios_url
- android_url
- desktop_url
- redirect_type
- expires_at

This ensures device routing works correctly after editing a link to add or modify
device-specific redirect URLs.
@github-actions
Copy link
Copy Markdown

🚀 Ephemeral Environment Deployed (Unified Worker)

Application: https://rushomon-pr-340.piffio.workers.dev

This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly).

This environment will be automatically cleaned up when the PR is closed.

Worker: rushomon-pr-340


💡 Tip: To skip preview deployment, add the skip-preview label to this PR.

@github-actions
Copy link
Copy Markdown

🚀 Ephemeral Environment Deployed (Unified Worker)

Application: https://rushomon-pr-340.piffio.workers.dev

This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly).

This environment will be automatically cleaned up when the PR is closed.

Worker: rushomon-pr-340


💡 Tip: To skip preview deployment, add the skip-preview label to this PR.

When editing a link and removing device-specific URLs, the frontend now
correctly sends clear_ios_url, clear_android_url, and clear_desktop_url
flags to ensure URLs are cleared in both D1 and KV stores.
@github-actions
Copy link
Copy Markdown

🚀 Ephemeral Environment Deployed (Unified Worker)

Application: https://rushomon-pr-340.piffio.workers.dev

This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly).

This environment will be automatically cleaned up when the PR is closed.

Worker: rushomon-pr-340


💡 Tip: To skip preview deployment, add the skip-preview label to this PR.

@piffio piffio merged commit 60a9878 into main Apr 27, 2026
9 checks passed
@github-actions
Copy link
Copy Markdown

🧹 Ephemeral Environment Cleaned Up

Resources for PR #340 cleanup summary:

Resource Status
Worker rushomon-pr-340 ✅ Deleted
KV Namespace URL_MAPPINGS_pr_340 ✅ Deleted
D1 Database rushomon-pr-340 ✅ Deleted
R2 Bucket rushomon-assets-pr-340 ✅ Deleted

Cleanup completed automatically when PR was closed.

Note: If this PR had the skip-preview label, resources were still cleaned up because they were deployed before the label was added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Device based routing

1 participant