Przejdź do treści
cutty.dev
Wszystkie posty

Auto-prefix URL — drobiazg który oszczędza minuty

cutty.dev rozpoznaje gdy wkleisz adres bez https:// i sam go dodaje. Brzmi błaho. W praktyce to różnica między dwoma sekundami a kliknięciem 'spróbuj jeszcze raz'.

Wpisujesz w formularz allegro.pl. Klikasz. I co?

W większości skracarek dostajesz w tym momencie komunikat o błędzie. Coś w stylu "to nie jest poprawny adres URL". Bo nie ma https:// z przodu. Więc cofasz się, dopisujesz protokół, klikasz jeszcze raz, i dopiero teraz masz swój krótki link.

cutty.dev tego nie robi. Po prostu sam dokleja https:// i jedzie dalej, jakby nigdy nic.

Wiem jak to brzmi. Jak feature, który ledwo zasługuje na akapit, nie mówiąc o całym wpisie. A jednak siedzę i o tym piszę, bo akurat ten drobiazg jest dla mnie małym manifestem tego, jak w ogóle myślę o budowaniu narzędzia auto-prefix URL i całej reszty tych niewidzialnych ułatwień.

Dwie sekundy kontra dwadzieścia

Policzmy. Naprawdę, na liczbach, bo inaczej to tylko gadanie.

Ścieżka pierwsza: wklejasz, masz link, zamykasz okno. Dwie sekundy. Może trzy.

Ścieżka druga: wklejasz, błąd, czytasz komunikat (sekunda czy dwie żeby zrozumieć o co chodzi), dopisujesz protokół, klikasz jeszcze raz, dopiero teraz link. Piętnaście, dwadzieścia sekund. Plus ten malutki moment irytacji, to ciche "a no tak, protokół", który nic nie kosztuje pojedynczo, ale narasta.

A teraz pomnóż przez to, ile razy w miesiącu wklejasz jakiś adres. U mnie to dziesiątki. U kogoś kto zarządza linkami zawodowo — setki. Nagle ten "ledwo wart wzmianki" drobiazg odkłada się w minuty miesięcznie. Na osobę.

To jest właśnie ta arytmetyka, którą większość ludzi pomija, bo każdy pojedynczy przypadek wygląda na za mały, żeby się nim przejmować.

Co tam właściwie siedzi pod spodem

Mechanizm jest banalny i wcale tego nie ukrywam. Wklejasz tekst do pola. Zanim cokolwiek poleci na serwer, kawałek JavaScriptu sprawdza, czy to co wpisałeś zaczyna się od jakiegoś protokołu — http://, https://, ftp://, mailto:, cokolwiek. Jeśli się nie zaczyna, system zakłada że masz na myśli zwykłą domenę i dokleja https:// z przodu.

W praktyce:

  • allegro.pl zamienia się w https://allegro.pl
  • github.com/twoj-profil/projekt w https://github.com/twoj-profil/projekt
  • www.gazeta.pl w https://www.gazeta.pl

A jeśli protokół już tam jest, choćby dziwny, system go nie nadpisuje. Zostawia i sprawdza dalej, co z tym fantem zrobić. http://example.com przechodzi (dozwolone). ftp://example.com leci do kosza, bo akceptujemy tylko http i https. A javascript:alert(1) wylatuje natychmiast, bo to nie adres, to próba wstrzyknięcia czegoś paskudnego (klasyczny XSS, dziękujemy, nie).

Dlaczego ja to mam, a połowa rynku nie

Tu robi się ciekawie, bo odpowiedź jest trochę śmieszna.

Standardowy sposób walidacji adresu w przeglądarce to konstruktor new URL(string). I ten konstruktor jest twardy. Bezkompromisowy. Nie ma protokołu — rzuca błędem. new URL("allegro.pl") zwraca ci po prostu TypeError i tyle.

I wiesz co? To jest poprawne zachowanie. Dla ogromnej większości aplikacji dokładnie tego chcesz. Ale w formularzu do skracania linków, gdzie człowiek kopiuje adres z paska przeglądarki albo z czyjejś wiadomości, ta surowość zamienia się z zalety w przeszkodę. Nagle narzędzie, które ma ci oszczędzać czas, każe ci poprawiać po sobie coś, co przecież doskonale rozumie.

Obejście tego to dosłownie kilka linii:

function sanitizeUrl(input) {
  const trimmed = input.trim();
  const hasProtocol = /^[a-z][a-z0-9+.-]*:/i.test(trimmed);
  const normalized = hasProtocol ? trimmed : "https://" + trimmed;
  // dalej leci normalna walidacja przez new URL(normalized)
}

Pięć linijek. Kilkanaście sekund mniej tarcia, dziennie, dla każdego kto wkleja adresy. Szczerze nie wiem, czemu to nie jest standard wszędzie. Podejrzewam, że chodzi o to, że "tak po prostu działa konstruktor URL" i nikomu nie chciało się tego dotknąć. Inercja, nie zła wola.

Mała dygresja o tym, co znaczy "standardowo"

Bo ta historia z new URL() to świetny przykład czegoś szerszego. Mnóstwo rzeczy, które w oprogramowaniu uchodzą za "tak się robi", to tak naprawdę "tak wyszło z domyślnych ustawień jakiejś biblioteki, której nikt nie kwestionował". Strict mode konstruktora nie jest decyzją projektantów cutty ani konkurencji — to decyzja autorów specyfikacji URL, podjęta w zupełnie innym kontekście, dla zupełnie innych zastosowań.

A potem cały rynek dziedziczy ten domyślny wybór i nazywa go "standardem". Mam wrażenie, że najlepsze produkty rodzą się dokładnie w tych miejscach, gdzie ktoś się zatrzymał i zapytał: chwila, czy to akurat zachowanie służy mojemu użytkownikowi, czy tylko mojej bibliotece? Najczęściej odpowiedź brzmi: bibliotece. I wtedy warto pięcioma linijkami przejść na stronę człowieka.

Tych drobiazgów jest więcej, niż widać

Auto-prefix to tylko jeden z wielu takich elementów, których nie znajdziesz na żadnej liście funkcji. Bo gdyby je tam wpisać, każdy z osobna wyglądałby na śmiesznie mały:

  • przycinanie spacji przed walidacją, żeby przypadkowa spacja na końcu wklejonego adresu nie zepsuła wszystkiego
  • zachowywanie kotwicy, czyli #section w https://example.com/page#section nie znika po skróceniu
  • parametry zapytania (?utm_source=test) przechodzą w całości, nic się nie ucina po drodze
  • domeny z polskimi znakami, źdźbło.pl, lecą automatycznie na punycode
  • polskie litery we własnej końcówce zamieniane na ASCII (różowy-link staje się rozowy-link)
  • niebezpieczne protokoły — javascript:, data:, file: — odbijane z konkretnym, zrozumiałym komunikatem

(Jest jeszcze planowane automatyczne podbicie http:// do https://, gdy serwer docelowy obsługuje szyfrowanie. To akurat jeszcze nie działa na żywo, więc nie będę udawać.)

Każdy z tych szczegółów oszczędza komuś pięć, dziesięć, trzydzieści sekund i jedno westchnienie. Pojedynczo nic. Razem to różnica między "działa OK" a "lubię z tego korzystać".

Co chciałbym jeszcze dorobić

Lista życzeń na przyszłość, bo myślenie o tym sprawia mi po prostu frajdę:

  • inteligentne wklejanie — wykryć adres schowany w środku zdania i wyłuskać sam URL spomiędzy słów
  • wklejanie hurtem — lista adresów, jeden na linijkę, i z każdego od razu osobny krótki link
  • podpowiadane końcówki — na podstawie tytułu strony docelowej zaproponować trzy markowe sluggi do wyboru
  • podgląd Open Graph od razu po wklejeniu, jeszcze zanim klikniesz "skróć"

Każde z tego to znowu "pięciolinijkowa funkcja, która wygląda na nic". A wszystkie razem? To właśnie ta granica między narzędziem, które jest w porządku, a takim, po które sięgasz codziennie bez zastanowienia. Jeśli chcesz zobaczyć, jak to działa teraz, wklej w cutty.dev cokolwiek bez protokołu — allegro.pl, github.com, news.ycombinator.com — i zobacz, że nic ci nie zarzuca pod nogi.

Na koniec, trochę osobiście

Długo myślałem, że produkty wygrywają wielkimi funkcjami. Tym jednym efektownym czymś, co da się pokazać na slajdzie i o czym napiszą ludzie. I owszem, czasem tak jest.

Ale im dłużej buduję cutty, tym mocniej czuję, że lojalność użytkownika rodzi się gdzie indziej — w tych setkach mikrosekund, których nikt świadomie nie zauważa. Nie pamiętasz, że narzędzie samo dodało ci https://. Pamiętasz tylko ogólne wrażenie, że "jakoś dobrze się tego używa", "nie wkurza". To wrażenie nie bierze się znikąd. Składa się z dziesiątek pięciolinijkowych decyzji, których pojedynczo nikt by nie obronił przed sobą jako "warte czasu".

Może właśnie na tym polega rzemiosło. Nie na tym jednym wielkim ruchu, tylko na uporze, żeby raz po raz stawać po stronie człowieka przy formularzu — nawet jeśli chodzi o nędzne dwie sekundy. A ty? Co cię ostatnio wkurzyło w jakimś narzędziu tak drobnego, że aż wstyd się przyznać? Bo zwykle właśnie tam siedzi najlepsza robota do zrobienia.