Auto-prefix URL — мелочь, которая экономит минуты
cutty.dev распознает, когда вы вставляете адрес без https://, и сам его добавляет. Звучит пустяково. На практике это разница между двумя секундами и нажатием кнопки «попробовать еще раз».
Вы вводите в форму allegro.pl. Нажимаете. И что?
В большинстве сокращателей в этот момент вы получаете сообщение об ошибке. Что-то вроде "это неверный URL-адрес". Потому что впереди нет https://. Поэтому вы возвращаетесь назад, дописываете протокол, кликаете еще раз, и только теперь у вас есть ваша короткая ссылка.
cutty.dev этого не делает. Он просто сам приклеивает https:// и идет дальше, как ни в чем не бывало.
Я знаю, как это звучит. Как фича, которая едва заслуживает абзаца, не говоря уже о целой записи. И все же я сижу и пишу об этом, потому что именно эта мелочь является для меня маленьким манифестом того, как я вообще думаю о создании инструмента auto-prefix URL и всей остальной совокупности этих невидимых упрощений.
Две секунды против двадцати
Давайте посчитаем. На самом деле, на цифрах, потому что иначе это просто пустая болтовня.
Первый путь: вставляешь, получаешь ссылку, закрываешь окно. Две секунды. Может, три.
Второй путь: вставляешь, ошибка, читаешь сообщение (секунда или две, чтобы понять, в чем дело), дописываешь протокол, кликаешь еще раз, и только теперь ссылка. Пятнадцать, двадцать секунд. Плюс этот крошечный момент раздражения, это тихое «а, точно, протокол», которое по отдельности ничего не стоит, но накапливается.
А теперь умножьте это на то, сколько раз в месяц вы вставляете какой-либо адрес. У меня это десятки. У того, кто управляет ссылками профессионально — сотни. Внезапно эта «едва заслуживающая упоминания» мелочь складывается в минуты ежемесячно. На человека.
Это именно та арифметика, которую большинство людей упускает из виду, потому что каждый отдельный случай кажется слишком незначительным, чтобы им заниматься.
Что на самом деле находится под капотом
Механизм банален, и я этого совсем не скрываю. Вы вставляете текст в поле. Прежде чем что-либо отправится на сервер, фрагмент JavaScript проверяет, начинается ли введенный вами текст с какого-либо протокола — http://, https://, ftp://, mailto: или любого другого. Если он не начинается с него, система предполагает, что вы имеете в виду обычный домен, и приклеивает https:// в начало.
На практике:
allegro.plпревращается вhttps://allegro.plgithub.com/twoj-profil/projektвhttps://github.com/twoj-profil/projektwww.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 — это лишь один из многих таких элементов, которые вы не найдете ни в одном списке функций. Потому что если бы их туда вписали, каждый по отдельности выглядел бы смешно маленьким:
- обрезка пробелов перед валидацией, чтобы случайный пробел в конце вставленного адреса не испортил всё
- сохранение якоря, то есть
#sectionвhttps://example.com/page#sectionне исчезает после сокращения - параметры запроса (
?utm_source=test) проходят целиком, ничего не обрезается по пути - домены с польскими символами,
źdźbło.pl, автоматически преобразуются в punycode - польские буквы в собственном окончании заменяются на ASCII (
różowy-linkстановитсяrozowy-link) - опасные протоколы —
javascript:,data:,file:— отклоняются с конкретным, понятным сообщением
(Также планируется автоматическое обновление http:// до https://, если целевой сервер поддерживает шифрование. Это пока не работает в режиме реального времени, так что я не буду делать вид.)
Каждая из этих деталей экономит кому-то пять, десять, тридцать секунд и один вздох. По отдельности — ничего. Вместе это разница между «работает нормально» и «мне нравится этим пользоваться».
Что бы я еще хотел добавить
Список желаний на будущее, потому что мысли о них просто доставляют мне удовольствие:
- интеллектуальная вставка — обнаружить адрес, спрятанный внутри предложения, и извлечь только сам URL из текста
- массовая вставка — список адресов, по одному на строку, и для каждого сразу создается отдельная короткая ссылка
- предлагаемые окончания — на основе заголовка целевой страницы предложить три фирменных слага на выбор
- предпросмотр Open Graph сразу после вставки, еще до того, как вы нажмете "сократить"
Каждое из этого снова «пятистрочная функция, которая ничего из себя не представляет». А все вместе? Это именно та грань между инструментом, который просто нормальный, и тем, к которому ты обращаешься каждый день не задумываясь. Если хочешь увидеть, как это работает прямо сейчас, вставь в cutty.dev что угодно без протокола — allegro.pl, github.com, news.ycombinator.com — и увидишь, что он не ставит тебе подножек.
В конце, немного личного
Я долго думал, что продукты выигрывают за счет масштабных функций. За этой одной эффектной вещью, которую можно показать на слайде и о которой напишут люди. И да, иногда это так.
Чем дольше я создаю cutty, тем сильнее чувствую, что лояльность пользователя рождается в другом месте — в тех сотнях микросекунд, которые никто не замечает осознанно. Вы не помните, что инструмент сам добавил вам https://. Вы помните только общее впечатление, что «пользоваться этим как-то удобно», «не раздражает». Это впечатление не берется из ниоткуда. Оно состоит из десятков пятистрочных решений, которые по отдельности никто бы не смог оправдать перед самим собой как «заслуживающие затраченного времени».
Может быть, именно в этом и заключается мастерство. Не в одном великом движении, а в упорстве вставать на сторону человека при заполнении формы — даже если речь идет о жалких двух секундах. А ты? Что тебя в последнее время разозлило в каком-нибудь инструменте настолько мелко, что даже стыдно признаться? Потому что обычно именно там и кроется лучшая работа, которую предстоит сделать.