dub icon indicating copy to clipboard operation
dub copied to clipboard

[Feature Request] Disable Case Sensitivity for Short Links (Rewrite to Lowercase)

Open abass opened this issue 2 years ago β€’ 12 comments

In general, having 2 identical links like: https://efficient.link/youtube https://efficient.link/YouTube

Should not be treated as 2 separate short links. And with social media and smart phones, automatic capitalization like this happens all the time, resulting in a dead link.

I can see someone maybe wanting capitalization to work if they are doing random strings and characters (I suppose), but it has always been more of a pain than help.

Would be cool if Dub allowed the rewriting of any uppercase letters to lowercase to prevent this from happening?

Appreciate it!

abass avatar Sep 03 '23 17:09 abass

I don't think it is a good idea. Lowercasing the short code would increase chances of collision in the long run.

mithleshjs avatar Sep 03 '23 19:09 mithleshjs

@mithleshjs any chance you can explain this thought a bit more? I'm thinking of it more being a settings toggle or even just a URL rewrite feature that allows the user to program a URL rewrite to be all lower-case for example.

abass avatar Sep 04 '23 06:09 abass

@mithleshjs any chance you can explain this thought a bit more? I'm thinking of it more being a settings toggle or even just a URL rewrite feature that allows the user to program a URL rewrite to be all lower-case for example.

Check this collision calculator - https://zelark.github.io/nano-id-cc/ Though it is specific to nanoid but you will get the idea.

mithleshjs avatar Sep 04 '23 07:09 mithleshjs

Thanks for the suggestion! Might add a link-specific option for this in the future, but for now, the default is to make all links case-sensitive (I believe this is the norm amongst popular link management tools like Bitly/Short.io as well).

steven-tey avatar Sep 06 '23 04:09 steven-tey

That's helpful, appreciate the consideration and explanation from everyone on this point!

-- Alex Bass Founder & Head of Product Efficient App ( https://efficient.app/?ref=email-signature ) | Efficient VC ( https://efficientvc.com/?ref=email-signature )

Connect with me: read.cv ( https://alexbass.xyz/?ref=email-signature ) | LinkedIn ( https://linkedin.com/in/alexhbass ) | Twitter ( https://twitter.com/alexhbass ) | YouTube ( https://efficient.link/youtube ) | VC Journey ( https://efficientvc.com/?ref=email-signature )

Looking for software inspiration? Check out our new recommended software stacks ( https://efficient.app/stacks?ref=email-signature ) and top picks ( https://efficient.app/top-picks?ref=email-signature ) !

Know a company that can use our help? Send them a Free Efficiency Audit ( https://efficient.app/audit?ref=email-signature ) πŸš€

Typed joyfully with Canary ( https://efficient.link/canary )

Sent via Superhuman ( https://efficient.link/r/superhuman ) (get 1 free month)

On Wed, Sep 6 2023 at 6:18 AM, Steven Tey < @.*** > wrote:

Thanks for the suggestion! Might add a link-specific option for this in the future, but for now, the default is to make all links case-sensitive (I believe this is the norm amongst popular link management tools like Bitly/Short.io as well).

β€” Reply to this email directly, view it on GitHub ( https://github.com/steven-tey/dub/issues/363#issuecomment-1707631899 ) , or unsubscribe ( https://github.com/notifications/unsubscribe-auth/ABKAHSQJDPOI77JYOT5LWFLXY72S7ANCNFSM6AAAAAA4JOJAUM ). You are receiving this because you authored the thread. Message ID: <steven-tey/dub/issues/363/1707631899 @ github. com>

abass avatar Sep 09 '23 00:09 abass

This is crucial for me. I make a short-link so my users can easily go to a webapp I develop. Now, "regular" users don't understand why https://efficient.link/youtube and https://efficient.link/YouTube are different.

I understand that the norm amongst popular link management tools is to make case sensitive links, but this is why we have Dub right, to stand out with features the others don't have.

Why not make it a setting per link and let the default setting be "Case sensitive short link". This way the new feature does not intrude current users and let anyone decide for themselves if they want to create a case sensitive short-link or not.

patrickmast avatar Sep 23 '23 13:09 patrickmast

@patrickmast completely agree – we're thinking of potentially making links case insensitive by default for non dub.sh links (custom project links)

However, this would require a pretty substantial refactor of our current setup so it probably won't happen for another month or so (or at least until #73 ships πŸ˜…)

steven-tey avatar Sep 24 '23 03:09 steven-tey

That sounds super reasonable πŸ‘Œ appreciate the consideration!

-- Alex Bass Founder & Head of Product Efficient App ( https://efficient.app/?ref=email-signature ) | Efficient VC ( https://efficientvc.com/?ref=email-signature )

Connect with me: read.cv ( https://alexbass.xyz/?ref=email-signature ) | LinkedIn ( https://linkedin.com/in/alexhbass ) | Twitter ( https://twitter.com/alexhbass ) | YouTube ( https://efficient.link/youtube ) | VC Journey ( https://efficientvc.com/?ref=email-signature )

Looking for software inspiration? Check out our new recommended software stacks ( https://efficient.app/stacks?ref=email-signature ) and top picks ( https://efficient.app/top-picks?ref=email-signature ) !

Know a company that can use our help? Send them a Free Efficiency Audit ( https://efficient.app/audit?ref=email-signature ) πŸš€

Typed joyfully with Canary ( https://efficient.link/canary )

Sent via Superhuman ( https://efficient.link/r/superhuman ) (get 1 free month)

On Sun, Sep 24 2023 at 5:26 AM, Steven Tey < @.*** > wrote:

@patrickmast ( https://github.com/patrickmast ) completely agree – we're thinking of potentially making links case insensitive by default for non dub.sh links (custom project links)

However, this would require a pretty substantial refactor of our current setup so it probably won't happen for another month or so (or at least until #73 ( https://github.com/steven-tey/dub/issues/73 ) ships πŸ˜…)

β€” Reply to this email directly, view it on GitHub ( https://github.com/steven-tey/dub/issues/363#issuecomment-1732466310 ) , or unsubscribe ( https://github.com/notifications/unsubscribe-auth/ABKAHSXY6WYEONYX5HPFAH3X36R43ANCNFSM6AAAAAA4JOJAUM ). You are receiving this because you authored the thread. Message ID: <steven-tey/dub/issues/363/1732466310 @ github. com>

abass avatar Sep 28 '23 14:09 abass

In general, having 2 identical links like: https://efficient.link/youtube https://efficient.link/YouTube

Should not be treated as 2 separate short links. And with social media and smart phones, automatic capitalization like this happens all the time, resulting in a dead link.

I can see someone maybe wanting capitalization to work if they are doing random strings and characters (I suppose), but it has always been more of a pain than help.

Would be cool if Dub allowed the rewriting of any uppercase letters to lowercase to prevent this from happening?

Appreciate it!

We'd definitely value the ability to choose on the project or custom domain level whether we want Dub to allow us to generate links that have the exact same characters as another active link we already have in Dub, and only differ in capitalisation.

Our use case is that we want to include short links in SMS messages which have a 160-character limit. We're struggling to stay within this 160-character limit as the body of our SMS message is already quite long. Thus we want to be able to create shortlinks with 2 character slugs to make them as short as possible.

Currently, via Dub's API we're unable to create the link rff.lt/AB, if we already have a link within Dub that's rff.lt/ab This limitation greatly reduces the number of unique active short links we can have.

26 characters in alphabet + 10 numbers (0-9) + 10 or so special characters ($-_.+!'() ) gives us 4646 = 2116 combinations.

But if we were allowed to differentiate on capitalisation we'd be able to get 72*72 = 5184 combinations

DouglasRose avatar Oct 30 '23 16:10 DouglasRose

Hey @steven-tey, any news on this? Thanks! πŸ™

patrickmast avatar Oct 30 '23 18:10 patrickmast

Sorry for the delay here @patrickmast! This requires a significant rewrite of the way we handle links right now so we'll need to put some more thought into it before making any changes to accomodate both sides of the equation. Appreciate the patience here guys! πŸ™

steven-tey avatar Nov 18 '23 05:11 steven-tey

Quick update: We just added a workaround here that could work for certain use cases – when you create a link, you can edit the key to account for all the possible cases you want and each of those links will still work.

Here's a demo:

https://github.com/dubinc/dub/assets/28986134/863cb0c0-6562-461c-b728-010f318a9b98

Caveat: If you update the link's destination URL / other attributes, only the final version will be updated.

This is definitely far from ideal – we will keep improving this in the future!

steven-tey avatar Dec 17 '23 03:12 steven-tey

I've been doing some thinking on this issue. I don't think you can support both case-insensitive slugs and case-sensitive slugs in the same domain.

  • The lookup logic wouldn't work since you don't know what one to look for in Redis
  • That would add a lot of confusion to the platform around UX
  • It would add a weird edge-case where some slugs are using one permutation (case sensitive ones) and some are using X permutations (case insensitive ones), so they would be unequal in size in terms of how many of the total possible slugs they take up. Matters less but could be a pain down the road.

IMO going with case insensitive is a better route because it's a weird UX to support dub.sh/twitter and dub.sh/Twitter as two different slugs and case sensitive opens holes for spoofing campaigns and has other downsides around people typing it out.

Adding to this, if we think about collisions for SMS campaigns few thoughts: You could add special sub-route like dub.sh/i/U3s9A that would support case-sensitive lookups for customized campaigns. The interesting thing here is moving to case-sensitive doesn't add as many options as you'd expect:

  • 5 digits
    • Case insensitive: 36^5 = 60,466,176
    • Case sensitive: 62^5 = 916,132,832
  • 6 digits
    • Case insensitive: 36^6 = 2,176,782,336
    • Case sensitive: 62^6 = 56,800,235,584
  • 7 digits
    • Case insensitive: 36^7 = 78,364,164,096
    • Case sensitive: 62^7 = 3,521,614,606,208

So for simplicity, you might be better off doing SMS campaigns at 7-digit case insensitive for now and move to a more complex model in the future when you run through the 78 billion entries (85 times bigger than 5-digit case insensitive).

zlwaterfield avatar Jan 06 '24 22:01 zlwaterfield

Did a bit more brainstorming with @zlwaterfield and I think we came up with the best way to support all 3 use cases:

  • Case insensitive (default behavior)
  • Case sensitive
  • Redirect rule (#529)

We'd convert our existing Redis setup to use hashes instead of the existing string setup – with the domain as the hash identifier. Reasoning:

E.g.:

HSET dub.sh github { url: 'https://github.com/dubinc/dub' }

And then, when we get a request, we'll do a HMGET to get the following:

  • the domain's metadata (regular redirect or redirect rule)
  • regular case of the key
  • lowercase of the key

Here are some examples:

  1. Regular redirects (case insensitive)
  • Requested link: dub.sh/GitHub
  • Command: HMGET dub.sh _metadata GitHub github
  • Results:
    • _metadata: { type: 'redirect', case: 'insensitive' }
    • GitHub: (nil)
    • github: { url: 'https://github.com/dubinc/dub' }
  1. Regular redirects (case sensitive)
  • Requested link: dub.sh/GitHub
  • Command: HMGET dub.sh _metadata GitHub github
  • Results:
    • _metadata: { type: 'redirect', case: 'sensitive' }
    • GitHub: { url: 'https://github.com/dubinc/dub' }
    • github: (nil)
  1. Redirect rule
  • Requested link: dub.sh/GitHub
  • Command: HMGET dub.sh _metadata GitHub github
  • Results:
    • _metadata: { type: 'redirect_rule', url: 'https://github.com/dubinc/dub' }
    • GitHub: (nil)
    • github: (nil)

Caveats:

  1. This limits the customization to a per-domain basis – meaning you can't do both case sensitive and/or case insensitive and/or redirect rule for one single domain
  2. The case sensitive redirects will only be stored in Redis since MySQL doesn't support case sensitive indices.

Thoughts? Feedback?

steven-tey avatar Jan 07 '24 02:01 steven-tey

From a user's perspective, having more options is always beneficial. While your current proposal is a significant step forward, considering a setting per link for "case sensitivity" could provide even more flexibility. This way, users could customize the behavior for individual links within a domain, offering a fine-grained control over their redirection preferences.

Moreover, having a default setting per domain is a practical approach, ensuring a seamless experience for users who might not want to delve into specific settings for every link. The proposed changes, especially the shift to using hashes in the Redis setup, seem promising for improving memory efficiency and simplifying key purging.

As you move forward, perhaps exploring the feasibility of incorporating a per-link setting for case sensitivity and redirect rules could add an extra layer of customization. This could cater to users with diverse requirements, making your system even more versatile.

Overall, it's an exciting development, and I look forward to seeing how these enhancements progress. Thanks for the continuous efforts to refine and expand the functionality!

πŸ˜€

Patrick

patrickmast avatar Jan 07 '24 15:01 patrickmast

@patrickmast does have an interesting point. What if redirect rules were just a function of a new URL instead of a donation setting?

That way I could make a new URL that's: https://eff.li/yt/* and tell it to go to https://efficient.yt/$1

And anyone that visits eff.li/yt/* would be redirected, but show under the stats of the link. Going at the domain-level might not make as much sense as using the existing new link infrastructure and adding redirect rules at that level. Obviously a redirect rule could be made which takes priority over a different link (e.g. creating a link afterward for eff.li/yt/test -> destination would in theory not work, unless of you said "exact match respects the specific URL redirect, and if no exact match exists, fall back to the URL with the redirect rule) that way you could even have a one-off override which is super interesting πŸ‘€

Anyway, not sure how clear or how much sense I'm making, just thinking that it might be more powerful to have these redirect rules actually at the specific URL level instead of the over-arching domain level, it might just be an order of operations thing to solve in that case.

abass avatar Jan 08 '24 15:01 abass

That way I could make a new URL that's: eff.li/yt* and tell it to go to efficient.yt/$1

Yeah we could potentially do that – we'll just need to update the _metadata field for eff.li hash to include all the redirect rules:

eff.li: _metadata β†’ { case: 'insensitive', redirect_rules: [ pattern: '', url: '' ] }

steven-tey avatar Jan 09 '24 03:01 steven-tey

We just shipped this! :star-struck_cat:

https://dub.co/changelog/case-insensitive-links

steven-tey avatar Jan 28 '24 06:01 steven-tey

Woop woop! Amazing, thanks @steven-tey β€” this is a big deal especially with mobile phones and auto-correct. The number of times it autocorrects to "/YouTube" instead of leaving it "/youtube" is... well a lot 😁

abass avatar Jan 28 '24 06:01 abass

Thank you!! This is an awesome feature and makes Dub.co even more special! Five star commit! ⭐️⭐️⭐️⭐️⭐️

patrickmast avatar Jan 28 '24 10:01 patrickmast