Auto-prefix URL — 몇 분을 아껴주는 사소한 기능
cutty.dev는 https:// 없이 주소를 붙여넣으면 이를 인식하여 자동으로 추가해 줍니다. 사소하게 들릴 수도 있지만, 실제로는 2초의 차이와 '다시 시도'를 클릭해야 하는 번거로움 사이의 차이를 만듭니다.
allegro.pl 양식에 입력합니다. 클릭합니다. 그래서 어떻게 되었나요?
대부분의 단축 서비스에서는 이 시점에 오류 메시지가 나타납니다. "유효한 URL이 아닙니다"와 같은 형태입니다. 앞부분에 https://가 없기 때문입니다. 그래서 뒤로 돌아가 프로토콜을 추가하고 다시 클릭하면, 그제서야 짧은 링크를 얻을 수 있습니다.
cutty.dev는 그렇게 하지 않습니다. 그냥 아무 일도 없었다는 듯이 스스로 https://를 붙이고 계속 진행합니다.
어떻게 들릴지 알고 있습니다. 전체 포스트는커녕 단락 하나를 차지하기에도 아쉬운 기능처럼 들리겠죠. 하지만 저는 이렇게 앉아 이 글을 쓰고 있습니다. 왜냐하면 바로 이 작은 디테일이 auto-prefix URL 도구를 구축하고 그 외의 모든 보이지 않는 편의 기능들을 제가 어떤 방식으로 생각하는지에 대한 저만의 작은 선언문이기 때문입니다.
2초 대 20초
계산해 봅시다. 정말로, 숫자로 말이죠, 그렇지 않으면 그저 말뿐이니까요.
첫 번째 경로: 붙여넣고, 링크를 확인하고, 창을 닫습니다. 2초. 어쩌면 3초.
두 번째 경로: 붙여넣기, 오류 발생, 메시지 읽기 (무슨 일인지 이해하는 데 1~2초), 프로토콜 추가 작성, 다시 클릭, 그리고 이제서야 링크. 15, 20초 소요. 여기에 아주 짧은 짜증의 순간, 즉 혼자서 나지막이 내뱉는 "아 맞다, 프로토콜"까지 더해지면, 하나씩은 비용이 들지 않지만 점점 쌓이게 됩니다.
이제 이것에 한 달 동안 특정 주소를 몇 번이나 붙여넣는지 곱해보세요. 저의 경우 수십 번입니다. 링크를 전문적으로 관리하는 사람이라면 수백 번일 수도 있습니다. 갑자기 이 "거의 언급할 가치도 없는" 사소한 일이 한 사람당 매달 몇 분의 시간으로 쌓이게 됩니다.
이것이 바로 대부분의 사람들이 간과하는 산술입니다. 왜냐하면 각각의 개별 사례가 신경 쓰기에는 너무 작아 보이기 때문입니다.
그 아래에는 실제로 무엇이 들어있을까요?
메커니즘은 매우 단순하며 이를 전혀 숨기지 않습니다. 텍스트를 필드에 붙여넣습니다. 데이터가 서버로 전송되기 전에, JavaScript 조각이 입력한 내용이 특정 프로토콜 — http://, https://, ftp://, mailto: 등 — 로 시작하는지 확인합니다. 만약 시작하지 않는다면, 시스템은 사용자가 일반 도메인을 의도한 것으로 간주하고 앞에 https://를 붙입니다.
실제 적용 사례:
allegro.pl이https://allegro.pl로 변경됩니다github.com/twoj-profil/projekt가https://github.com/twoj-profil/projekt로 변경됩니다www.gazeta.pl이https://www.gazeta.pl로 변경됩니다
만약 프로토콜이 이미 그곳에 존재한다면, 비록 이상할지라도 시스템은 이를 덮어쓰지 않습니다. 그대로 두고 어떻게 처리할지 계속 확인합니다. http://example.com은 통과됩니다 (허용됨). ftp://example.com은 휴지통으로 버려집니다. 왜냐하면 우리는 http와 https만 허용하기 때문입니다. 그리고 javascript:alert(1)은 즉시 제거됩니다. 이것은 주소가 아니라 무언가 불쾌한 것을 삽입하려는 시도이기 때문입니다 (전형적인 XSS, 사양하겠습니다).
왜 나만 가지고 있고, 시장의 절반은 없는가
여기가 흥미로워지는데, 왜냐하면 답변이 약간 웃기기 때문입니다.
브라우저에서 주소를 검증하는 표준적인 방법은 new URL(string) 생성자를 사용하는 것입니다. 그리고 이 생성자는 매우 엄격합니다. 타협이 없습니다. 프로토콜이 없으면 — 에러를 발생시킵니다. new URL("allegro.pl")은 그냥 TypeError를 반환하고 끝입니다.
그리고 그거 아세요? 이것은 올바른 동작입니다. 대다수의 애플리케이션에서는 정확히 당신이 원하는 방식이죠. 하지만 브라우저 주소창이나 누군가의 메시지에서 주소를 복사해 넣는 링크 단축 양식의 경우, 이러한 엄격함은 장점에서 장애물로 변합니다. 갑자기 당신의 시간을 절약해 주어야 할 도구가, 분명히 완벽하게 이해하고 있는 내용에 대해 당신에게 수정을 요구하게 됩니다.
이것을 우회하는 방법은 말 그대로 몇 줄뿐입니다:
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)
}
다섯 줄. 주소를 붙여넣는 모든 이들에게 매일 수십 초의 마찰을 줄여줍니다. 솔직히 왜 이것이 어디에서나 표준이 아닌지 모르겠습니다. 제 생각에는 "URL 생성기가 그냥 그렇게 작동하기" 때문이며, 아무도 이를 건드리고 싶어 하지 않았던 것 같습니다. 악의가 아니라 관성 때문입니다.
"표준적으로"라는 말이 무엇을 의미하는지에 대한 짧은 여담
new URL()에 관한 이 이야기는 더 넓은 의미를 보여주는 아주 좋은 예시입니다. 소프트웨어 개발에서 "원래 이렇게 하는 것"으로 여겨지는 수많은 것들은 사실 "아무도 의문을 제기하지 않은 어떤 라이브러리의 기본 설정이 그렇게 되어버린 결과"인 경우가 많습니다. 생성자의 strict mode는 cutty 설계자나 경쟁사의 결정이 아닙니다. 이는 완전히 다른 맥락에서, 완전히 다른 용도를 위해 내려진 URL 사양 작성자들의 결정입니다.
그리고 나면 시장 전체가 이 기본 설정을 상속받고 이를 "표준"이라고 부릅니다. 저는 최고의 제품들이 바로 누군가가 멈춰 서서 이렇게 질문한 지점에서 탄생한다는 인상을 받습니다: "잠깐, 이 동작이 내 사용자에게 도움이 되는 걸까, 아니면 단지 내 라이브러리에만 도움이 되는 걸까?" 대부분의 경우 대답은 '라이브러리'입니다. 그리고 바로 그때, 다섯 줄 정도의 코드로 인간의 편으로 돌아설 가치가 있습니다.
이 사소한 것들은 보이는 것보다 더 많습니다
Auto-prefix는 기능 목록 어디에서도 찾아볼 수 없는 수많은 요소 중 하나일 뿐입니다. 만약 그것들을 목록에 일일이 적어 넣는다면, 각각의 항목은 우스꽝스러울 정도로 작아 보일 것이기 때문입니다:
- 유효성 검사 전 공백 제거, 붙여넣은 주소 끝의 실수로 들어간 공백이 전체를 망치지 않도록 함
- 앵커 유지, 즉
https://example.com/page#section에서#section이 단축 후에도 사라지지 않음 - 쿼리 매개변수(
?utm_source=test)가 중간에 잘리지 않고 전체적으로 전달됨 - 폴란드어 문자가 포함된 도메인,
źdźbło.pl은 자동으로 punycode로 변환됨 - 커스텀 슬러그 내의 폴란드어 문자를 ASCII로 변환 (
różowy-link가rozowy-link가 됨) - 위험한 프로토콜 —
javascript:,data:,file:— 특정하고 이해하기 쉬운 메시지와 함께 차단됨
(대상 서버가 암호화를 지원하는 경우 http://를 https://로 자동으로 업그레이드하는 기능이 아직 계획 중입니다. 이 기능은 아직 라이브 환경에서 작동하지 않으므로, 거짓으로 말씀드리지 않겠습니다.)
이러한 세부 사항 하나하나가 누군가의 5초, 10초, 30초와 한 번의 한숨을 아껴줍니다. 개별적으로는 아무것도 아니지만, 모이면 "그냥 괜찮네"와 "사용하는 게 즐겁네" 사이의 차이를 만듭니다.
내가 추가로 더 하고 싶은 것
미래를 위한 위시리스트입니다. 왜냐하면 이런 생각을 하는 것 자체가 저에게는 정말 즐거움이기 때문입니다:
- 스마트 붙여넣기 — 문장 중간에 숨겨진 주소를 감지하고 단어들 사이에서 URL만 추출합니다
- 일괄 붙여넣기 — 한 줄에 하나씩 나열된 주소 목록을 입력하면 즉시 각각 별도의 짧은 링크로 변환합니다
- 추천 슬러그 — 대상 페이지의 제목을 기반으로 선택 가능한 세 가지 브랜드 슬러그를 제안합니다
- 붙여넣기 직후 Open Graph 미리보기 — "단축" 버튼을 클릭하기 전에도 바로 확인할 수 있습니다
이 모든 것은 다시 한번 "아무것도 아닌 것처럼 보이는 5줄짜리 함수"입니다. 그리고 이 모든 것이 합쳐지면 무엇일까요? 그것은 바로 괜찮은 수준의 도구와 고민 없이 매일 손이 가는 도구 사이의 경계입니다. 이것이 어떻게 작동하는지 지금 바로 확인하고 싶다면, cutty.dev에 프로토콜이 없는 아무것이나 — allegro.pl, github.com, news.ycombinator.com — 붙여넣어 보세요. 그리고 어떤 장애물도 당신을 방해하지 않는 것을 확인할 수 있습니다.
마지막으로, 약간 개인적인 이야기
오랫동안 저는 제품이 거대한 기능들로 승리한다고 생각했습니다. 슬라이드에 보여줄 수 있고 사람들이 글을 남길 만한, 그 단 하나의 인상적인 무언가 말이죠. 그리고 네, 때로는 정말 그렇습니다.
cutty를 더 오래 만들수록, 사용자 충성도는 다른 곳에서 생긴다는 것을 더 강하게 느낍니다. 바로 아무도 의식적으로 알아차리지 못하는 수백 마이크로초의 순간들 말이죠. 도구가 스스로 https://를 추가했다는 사실은 기억하지 못합니다. 그저 "사용하기 꽤 괜찮다", "짜증 나지 않는다"라는 막연한 인상만 기억할 뿐입니다. 이 인상은 결코 그냥 생겨나는 것이 아닙니다. 이는 단 하나만으로는 누구도 "시간을 들일 가치가 있다"라고 변호하지 못할 수십 개의 다섯 줄짜리 결정들이 모여 만들어진 것입니다.
어쩌면 바로 이것이 장인 정신의 본질일지도 모릅니다. 단 한 번의 거대한 움직임이 아니라, 설령 고작 2초에 불과할지라도 양식(form) 앞에서 끊임없이 사람의 편에 서고자 하는 고집 말입니다. 당신은 어떤가요? 최근 어떤 도구에서 차마 말하기 부끄러울 정도로 사소해서 화가 났던 적이 있나요? 왜냐하면 보통 바로 그곳에 가장 가치 있는 작업이 기다리고 있기 때문입니다.