Auto-prefix URL — pis detail, mis säästab minute
cutty.dev tuvastab, kui kleepid aadressi ilma https:// ja lisab selle ise. See kõlab trivialsena. Tegelikkuses on see erinevus kahe sekundi ja nupule 'proovi uuesti' vajutamise vahel.
Linkide lühendamise vormis sisestate allegro.pl. Enamik lühendajaid ütleb teile, et see ei ole korrektne URL, ja palub sisestada uuesti koos eesosa https:// ile. cutty.dev lisab lihtsalt ise https:// ja jätkab.
See kõlab nagu funktsioon, mis ei vääri peaaegu mainimist. Praktikas on see erinevus:
- "kleepisin sisse, mul on lühike link, sulan akna" (2 sekundit)
- "kleepisin sisse, viga, loen teadet, lisan https, uuesti, sain lingi" (15-20 sekundit)
Kordalda kordota selle arv, kui palju korda kuus URL-i kleepid, lisades ette frustratsiooni vead lugemisel ja hetke "ah joo, protseduur". Väike asi, mida mõõdetakse minutites inimese kohta kuus.
Mis täpset teeb cutty.dev
Lippasid teksti vormi. Enne serverile saatmist kontrollib JavaScript, kas see algab mõne protsolliga (http://, https://, ftp://, mailto: jne). Kui see ei ala**<0xC2><0xA0>**<0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2><0xA0><0xC2>
Tähendab:
allegro.pl→https://allegro.plgithub.com/twoj-profil/projekt→https://github.com/twoj-profil/projektwww.gazeta.pl→https://www.gazeta.pl
A kui sesuatu juba on protokoll (isegi kui see on vale), siis süsteem jätab selle muutmata ja kontrollib edasi:
http://example.com→ jääbhttp://example.com(lubatud)ftp://example.com→ keelatud (ainult http/https)javascript:alert(1)→ keelatud (XSS kaitse)
Miks mul on see ja teistel mitte
Enamik lühendajaid kasutavad standardset URL-i kontrolli läbi new URL(string). Konstruktor URL brauseri/JavaScriptis on strict — kui protokoll puudub, visatakse viga. Vaikimisi väljund new URL("allegro.pl") jaoks on TypeError.
See on enamik rakenduste puhul korrektne käitumine. Kuid linki lühendamise vormi puhul, kus kasutaja kleepib aadressiribalt või muust rakendusest kopeeritud URL-i, on see rangus takistus rather kui abi.
Lahendus võtab viis JavaScripti rida:
function sanitizeUrl(input) {
const trimmed = input.trim();
const hasProtocol = /^[a-z][a-z0-9+.-]*:/i.test(trimmed);
const normalized = hasProtocol ? trimmed : "https://" + trimmed;
// dalsza walidacja przez new URL(normalized)
}
Viis koodirida, kümne sekundi vähem frustratsiooni iga kasutaja kohta päevas. Ei tea, miks enamik turust seda ei tee. Võib-olla sest "standardselt" tähendab "nii toimib URL-i konstruktor".
UX-i pisidetailid on ebaproportsionaalselt olulised
cutty.dev-il on kümnemakümmend sarnast asja, mis ei ole ükski funktsioonide loettus, sest igaüks eraldi kõlab triviaalne:
- Trim whitespace enne valideerimist — lõuna tühikuga kleepitud URL ei põhjusta vigu
- Hash zachowany —
https://example.com/page#sectionsäilitab lühendamise pärast#section - Query strings zachowane —
?utm_source=testläbib ilma katkestamata - Automatic protocol upgrade —
http://muutubhttps://, kui algne URL toetab TLS-i (planeeritud, veel mitte LIVE) - IDN domains —
źdźbło.plkonverteeritakse automaatselt punycode'iks - Polskie znaki w slug — asendatakse automaatselt ASCII-ga lõpu loomisel (
różowy-link→rozowy-link) - Detect dangerous protocols —
javascript:,data:,file:,mailto:tõndetakse kindla teatega
Iga detail säästab kedagi 5–30 sekund ja hetke ärritust. Koos on see erinevus tussen "armastan seda rakendust" ja "töötab OK".
Mis edasi detailide UX-iga
Asjad, mida tahan tulevikus teha nimekiri:
- Smart paste — tuvasta, kui kasutaja kleepib teksti, mis sisaldab URL-i koos teiste sõnadega, ja eralda ainult URL
- Bulk paste — kleepitud URL-ide loetelu (üks rida kohta) loob korraga mitu lühikest linki
- Suggested slugs — sihtlehe pealkirja põhjal paku valimiseks 3 brändikatendust
- Auto-OG preview — näita Open Graph kaardi eelvaadet kohe pärast URL-i kleepmist, enne lühendamise klikkimist
Iga üks neist on samuti "viililine funktsioon, mis ei näata midagi". Kõik koos erinevad tööriha, mis on OK, ja tööriha, mida tahad igapäevaselt kasutada.
Proovi ise
Kleeli midagi — allegro.pl või github.com või news.ycombinator.com. Süsteem lisab ise protokolli ja jätkab edasi. Ilma ootamata, ilma veaga, ilma "proovi uuesti".
Kui teid huvitab selline UX-detail — andke teada, millisel suunas edasi liikuda. hello@cutty.dev.