en
Feedback

Don't get caught by a cheater! Telemetrio finds and tags such channels 👉 If you want to see the tag, subscribe

Code Ready | Frontend

Code Ready | Frontend

Open in Telegram

Авторский канал по Frontend разработке. Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3NJCKs

Show more

📈 Analytical overview of Telegram channel Code Ready | Frontend

Channel Code Ready | Frontend (@code_ready) in the Russian language segment is an active participant. Currently, the community unites 21 545 subscribers, ranking 6 157 in the Technologies & Applications category and 30 472 in the Russia region.

📊 Audience metrics and dynamics

Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 21 545 subscribers.

According to the latest data from 26 October, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by -42 over the last 30 days and by -20 over the last 24 hours, overall reach remains high.

  • Verification status: Not verified
  • Engagement rate (ER): The average audience engagement rate is 6.43%. Within the first 24 hours after publication, content typically collects 4.29% reactions from the total number of subscribers.
  • Post reach: On average, each post receives 1 386 views. Within the first day, a publication typically gains 925 views.
  • Reactions and interaction: The audience actively supports content: the average number of reactions per post is 23.
  • Thematic interests: Content is focused on key topics such as css, браузер, интерфейс, загрузка, api.

📝 Description and content policy

The author describes the resource as a platform for expressing subjective opinions:
“Авторский канал по Frontend разработке. Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3NJCKs”

Thanks to the high frequency of updates (latest data received on 27 October, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.

21 545
Subscribers
-2024 hours
-667 days
-4230 days
Posts Archive
Дедлайны горят, а твои глаза уже нет. Что делать, если ты за#бался и хочется просто залипать в телефоне? И вроде понимаешь, ч
Дедлайны горят, а твои глаза уже нет. Что делать, если ты за#бался и хочется просто залипать в телефоне? И вроде понимаешь, что НАДО, но от этого еще больше сопротивление. Если близкие думают, что ты зажрался, а тебе и самому от себя уже тошно, но как себя взбодрить – непонятно, советую посмотреть вот что: https://t.me/Manifestans Ты 100% себя узнаешь, а значит 100% получишь пользу от того, что там увидишь! Если ты еще не собрал пожитки и не ушел отшельником в лес – есть шанс тебя оживить и вернуть эмоции и интерес к жизни. Кликай сюда и начинай приходить в себя.

Добавляем дополнительную информацию с помощью тега ! Тег используется для отображения второстепенного текста, который имеет м
Добавляем дополнительную информацию с помощью тега <small>! Тег <small> используется для отображения второстепенного текста, который имеет меньшее значение по сравнению с основным содержимым. Он подходит для информации, которая полезна пользователю, но не является частью основного сообщения. Для чего <small> подойдёт идеально: • пояснения; • комментарии; • дисклеймеры; • предостережения; • копирайт; • информация о лицензии; • прочая правовая информация. Важно: <small> имеет семантическое значение, а не просто уменьшает размер текста. Для изменения визуального размера обычного текста лучше использовать CSS. 📣 Code Ready | #атрибут

Symbol: как добавлять внутренние свойства объектов без конфликтов! В JavaScript объекты часто используются разными частями приложения, библиотеками и компонентами одновременно. Иногда требуется добавить к существующему объекту дополнительные данные: состояние компонента, метаданные, кэш или внутренние флаги. Добавление обычных свойств может привести к конфликтам. Если такое имя уже используется другим кодом, одно значение может случайно заменить другое.
const element = {
  value: "button"
};

element.state = {
  mounted: true
};
Если свойство state уже существует в объекте, новое значение перезапишет старое. В больших приложениях такие ситуации могут быть сложными для поиска, особенно когда объект расширяется несколькими независимыми модулями. Для решения этой задачи существует Symbol — это примитивный тип данных, который создаёт уникальные ключи свойств объектов. Каждый созданный символ является уникальным, поэтому он не может случайно совпасть с обычным строковым свойством или другим символом.
const internalState = Symbol("internalState");

const component = {
  value: "button",

  [internalState]: {
    mounted: true
  }
};

console.log(component[internalState]);

// { mounted: true }
Теперь внутренние данные хранятся по уникальному ключу. Объект можно расширять дополнительным состоянием, не изменяя его публичную структуру. Даже если другой код добавит свойство с похожим названием, конфликт не возникнет:
component.internalState = false;

console.log(component[internalState]);

// { mounted: true }
Symbol-свойства имеют ещё одну особенность: они не отображаются в большинстве стандартных способов перебора объектов. Например, Object.keys() возвращает только строковые ключи:
Object.keys(component);

// ["value"]
Это позволяет хранить дополнительные данные внутри объекта, не добавляя их в обычное представление объекта и его публичный API. При необходимости получить символьные свойства можно явно:
Object.getOwnPropertySymbols(component);
Такой подход часто используется в библиотеках и компонентах, которым необходимо хранить внутренние данные, связанные с объектом. Например, можно добавить метаданные компонента:
const meta = Symbol("meta");

function initComponent(component) {
  component[meta] = {
    id: crypto.randomUUID(),
    createdAt: Date.now()
  };
}
После этого объект получает внутреннюю информацию, но его внешний интерфейс остаётся неизменным:
component.id;

// undefined

component[meta].id;

// UUID
Кроме пользовательских символов, JavaScript содержит встроенные Symbol, которые позволяют изменять стандартное поведение объектов:
Symbol.iterator
Symbol.asyncIterator
Symbol.toPrimitive
Например, Symbol.iterator позволяет объекту поддерживать цикл for...of:
const collection = {
  items: ["a", "b"],

  [Symbol.iterator]() {
    return this.items[Symbol.iterator]();
  }
};

for (const item of collection) {
  console.log(item);
}
Важно понимать: Symbol не является механизмом настоящей приватности. Символьные свойства можно найти через:
Object.getOwnPropertySymbols();

Reflect.ownKeys();
Основная задача Symbol — создавать уникальные ключи и безопасно расширять объекты без риска конфликтов имён. Для настоящей приватности в классах JavaScript используются #private fields. 🔥 Symbol — практический инструмент для создания библиотек, компонентов и больших frontend-систем, где требуется добавлять внутренние данные, сохраняя чистый публичный API объекта. 📣 Code Ready | #практика

Издательский дом «Новые отраслевые медиа» собрал для вас лучшие каналы из сферы искусственного интеллекта и интернет-технологий, которые помогают своим подписчикам быть в курсе всех важных профессиональных новостей. Здесь - всё про ключевых игроков отрасли, государственное регулирование, инсайды и кейсы от отраслевых лидеров. ✅Серверная - канал об индустрии дата-центров: технологиях, инфраструктуре, облачных решениях, энергоэффективности и применении ЦОД в ключевых отраслях экономики. ✅Робосфера - канал об индустрии робототехники: технологии и тренды. Промышленные и сервисные роботы, коботы, автоматизация, ИИ, машинное зрение, автономные системы. ✅AI для бизнеса - всё об AI-решениях для бизнеса: внедрение, автоматизация, корпоративный ИИ, агенты. ✅ТехноРитейл - канал о производстве и продаже бытовой техники и электроники в России: бренды, e-com, маркетинг, retail tech. Подписывайтесь, и эти каналы смогут изменить вашу жизнь к лучшему! Реклама. Харламов А.Е. ИНН 712803816807. erid: 2W5zFJNTBaZ

👩‍💻 Отключает валидацию формы. Зачем нам валидация формы браузером, когда у нас есть JS? Атрибут novalidate используется у
👩‍💻 Отключает валидацию формы. Зачем нам валидация формы браузером, когда у нас есть JS? Атрибут novalidate используется у тега <form> и отключает стандартную валидацию полей браузером при отправке формы. По умолчанию браузер сам проверяет такие ограничения, как: • обязательные поля (required); • корректность email (type="email"); • формат данных (pattern); • минимальные и максимальные значения (min, max). После добавления novalidate эта проверка не выполняется, и отправка формы передаётся полностью под контроль JS или серверной логики. Важно: novalidate не отключает атрибуты в HTML, а только запрещает браузеру автоматически проверять их при отправке. 📣 Code Ready | #атрибут

Passive Event Listeners: оптимизация обработки touch- и wheel-событий! При обработке некоторых событий ввода браузеру необходимо понимать, может ли JavaScript-обработчик отменить стандартное поведение события. Например, при взаимодействии с экраном пользователь ожидает мгновенной прокрутки страницы. Однако обработчик touchmove может вызвать event.preventDefault() и заблокировать стандартный жест браузера. Если обработчик считается непассивным, браузеру может потребоваться дождаться завершения его выполнения, прежде чем начать или продолжить прокрутку. Обычный обработчик события:
window.addEventListener(
  'touchmove',
  event => {
    const touch = event.touches[0];

    console.log(
      touch.clientX,
      touch.clientY
    );
  },
  {
    passive: false
  }
);
В этом случае браузер должен учитывать, что обработчик потенциально может вызвать preventDefault(). Поэтому прокрутка может быть отложена до завершения выполнения JavaScript-кода. Чтобы явно указать, что обработчик не будет отменять стандартное поведение, используется параметр passive.
window.addEventListener(
  'touchmove',
  event => {
    const touch = event.touches[0];

    console.log(
      touch.clientX,
      touch.clientY
    );
  },
  {
    passive: true
  }
);
Теперь браузер знает, что обработчик не вызовет preventDefault(), и может обрабатывать прокрутку без ожидания завершения JavaScript-кода. Следует учитывать, что современные браузеры в некоторых случаях автоматически используют пассивный режим для обработчиков touchstart, touchmove, wheel и mousewheel, зарегистрированных на window, document или body. Конкретное поведение зависит от браузера, события и целевого элемента. Поэтому, если обработчик должен гарантированно вызывать preventDefault(), лучше явно указать:
{
  passive: false
}
Событие scroll отличается тем, что возникает после изменения позиции прокрутки и не может быть отменено через preventDefault(). Поэтому использование passive для scroll не даёт преимуществ производительности. Например:
window.addEventListener(
  'scroll',
  () => {
    const position = window.scrollY;

    document.querySelector(
      '.header'
    ).style.opacity = Math.min(
      position / 500,
      1
    );
  }
);
В данном примере при каждом вызове обработчика выполняется поиск элемента в DOM и изменяется его стиль. При высокой частоте событий это создаёт дополнительную нагрузку на основной поток. В подобных случаях эффективнее заранее сохранить ссылку на элемент, сократить объём выполняемой работы и при необходимости использовать requestAnimationFrame или throttling.
const header = document.querySelector('.header');

let scheduled = false;

window.addEventListener('scroll', () => {
  if (scheduled) {
    return;
  }

  scheduled = true;

  requestAnimationFrame(() => {
    header.style.opacity = Math.min(
      window.scrollY / 500,
      1
    );

    scheduled = false;
  });
});
debounce обычно применяют для действий, которые должны выполняться после завершения прокрутки, например для отправки аналитики или сохранения состояния интерфейса. Также важно учитывать, что passive: true запрещает отмену стандартного поведения события. Вызов:
event.preventDefault();
Внутри пассивного обработчика не остановит стандартное поведение браузера и обычно приведёт к предупреждению в консоли.
window.addEventListener(
  'touchmove',
  event => {
    event.preventDefault();
  },
  {
    passive: true
  }
);
passive: true целесообразно использовать, если обработчик только анализирует событие или обновляет интерфейс и ему не требуется вызывать preventDefault(). Если обработчик должен отменять стандартное поведение браузера, его нельзя делать пассивным. 🔥 Passive Event Listeners уменьшают задержки при обработке touch- и wheel-событий, поскольку браузеру не требуется ожидать возможного вызова preventDefault(). При этом они не устраняют проблемы, связанные с тяжёлыми JavaScript-обработчиками. 📣 Code Ready | #практика

На Stepik вышла программа «DevOps с нуля: от Linux до Kubernetes» Это комплексная программа из 5 практических курсов по ключе
На Stepik вышла программа «DevOps с нуля: от Linux до Kubernetes» Это комплексная программа из 5 практических курсов по ключевым технологиям DevOps: Linux, Git, Docker, GitLab CI/CD, Kubernetes Вы последовательно пройдёте путь от работы в Linux и управления кодом через Git до контейнеризации приложений, настройки CI/CD-пайплайнов и развёртывания в Kubernetes. Что вы изучите:
• работу с Linux и командной строкой • Git и контроль версий в реальных проектах • создание Docker-образов и запуск контейнеров • автоматизацию сборки, тестирования и деплоя в GitLab CI/CD • развёртывание и управление приложениями в Kubernetes • сети, хранилища, конфигурации и секреты • диагностику инфраструктуры и автоматизацию рутинных задач ... и многое другое
Все знания закрепляются на практике с помощью заданий с автопроверкой. Материал подаётся последовательно и понятным языком: с примерами, схемами и демонстрациями. Во время обучения можно задавать вопросы по урокам и заданиям, получать обратную связь и помощь при возникновении сложностей. После прохождения программы вы получите сертификат, который можно добавить в резюме. Скидка 20% на 48 часов: по промокоду READY20 стоимость всей программы составит 10 392 ₽. Открыть программу на Stepik

👩‍💻 Валидируем форму прямо в браузере. Без JavaScript, регистрации и смс! Псевдоклассы :valid и :invalid в CSS позволяют ст
👩‍💻 Валидируем форму прямо в браузере. Без JavaScript, регистрации и смс! Псевдоклассы :valid и :invalid в CSS позволяют стилизовать поля формы в зависимости от результата встроенной HTML-валидации. Они работают с ограничениями вроде required, pattern, min, max, type="email" и другими. Как это используется: • :valid — поле заполнено корректно; • :invalid — значение не прошло проверку; • можно менять цвет рамки, фона или отображать состояние поля. Это простой способ сделать форму более понятной для пользователя, не прибегая к JS. 📣 Code Ready | #свойство

👨‍💻 Front-End Web Development Resources — большая подборка ресурсов по frontend-разработке! Здесь собраны ресурсы по HTML, CSS, JavaScript, React, Angular, Vue.js, TypeScript, Git, UI/UX, адаптивной вёрстке, инструментам разработки и многим другим направлениям. Материалы подойдут как начинающим разработчикам, так и тем, кто уже работает и хочет расширить знания или быстро найти качественные источники по конкретной теме. Оставляю ссылочку: GitHub 📱 📣 Code Ready | #репозиторий

Красивые переносы заголовков! Часто последняя строка заголовка выглядит неаккуратно: одно-два коротких слова оказываются отде
Красивые переносы заголовков! Часто последняя строка заголовка выглядит неаккуратно: одно-два коротких слова оказываются отдельно. Обычно это исправляют вручную.
<h1>Новый<br>релиз CSS</h1>
Или вставляют &nbsp;, <wbr> и другие ручные переносы. Теперь с этим может помочь сам браузер.
h1 {  
text-wrap: balance;
}
Браузер старается более равномерно распределить текст между строками, чтобы заголовок выглядел аккуратнее. Лучше всего использовать это для коротких текстов: заголовков, подзаголовков, цитат и подписей. Для длинных абзацев есть отдельный режим.
p {
  text-wrap: pretty;
}
Он старается избегать неудачных переносов и слишком коротких последних строк. Если браузер его не поддерживает, текст просто будет переноситься как обычно. 🔥 text-wrap: balance и text-wrap: pretty позволяют заметно улучшить типографику буквально одной строкой CSS. 📣 Code Ready | #совет

Ищут 10 человек, чтобы собирали чат-ботов по шаблону, как пазлы. ЗП: от 5-9000₽ за вечер. Занятость: 3-4 часа в день. Опыт: не нужен. Как мы работаем: 1. Ты проходишь обучение пару недель; 2. Берёшь реальный проект из моей базы; 3. Собираешь бота по проверенной формуле; 4. Наставник контролирует процесс; 5. Получаешь деньги и закрепляешь клиента. Весь процесс занимает до 2х недель с нуля до первых денег на твою карту. Даниил из Балашихи был военнослужащим — с июля 2024 года начал создавать чат-ботов для бизнеса и уже заработал 4 млн. рублей. А главное теперь у него больше свободного времени на семью, друзей и развлечения. Да, ты не первый. 277 человек уже ведут постоянных клиентов по моей формуле. Ведь сайт со статистикой Wordstat показывает 10 786 запросов за месяц в поисковике от бизнеса на эту услугу. Заказов валом. Срочно нужны твои руки и голова. Чтобы быстро разобраться во всех нюансах — запускай бота Там пошаговый план как стартануть и гайд по клиентам. 8 мест ещё свободно

🐱 8 шпаргалок для веб-разработчика — полезная подборка по HTML, CSS, JavaScript, React и Git! На странице собрана крутая подборка из 8 полезных шпаргалок для веб-разработчиков. Здесь справочники по HTML, CSS, Grid Layout, Flexbox, JavaScript, React и Git с примерами кода, схемами и наглядными объяснениями. Полезно для frontend-разработчиков: можно быстро освежить знания по вёрстке, JavaScript и др. инструментам. 📌 Оставляю ссылочку: highload.tech 📣 Code Ready | #сайт

Range API — работа с диапазонами DOM и фрагментами документа! Иногда нужно изменить не весь элемент целиком, а только конкретный участок внутри него: выделенный текст, часть DOM или место для вставки нового элемента. В таких случаях работы со строками недостаточно, нужно обращаться напрямую к структуре DOM. Range позволяет описать участок документа между двумя точками в DOM и выполнять операции именно над этим фрагментом. Важно понимать разницу между Selection и Range. Selection хранит то, что пользователь выделил мышкой, а Range описывает конкретные границы этого выделения и даёт инструменты для работы с ним. Например, получим текущее выделение пользователя:
const selection = window.getSelection();

if (selection.rangeCount > 0) {
  const range = selection.getRangeAt(0);

  console.log(range.toString());
}
После получения Range мы можем работать с выбранным участком документа. Метод toString() удобен, когда нужен только текст выделения. Но он возвращает обычную строку и не сохраняет HTML-структуру внутри этого фрагмента. Например, есть такой DOM:
<p>
  Hello <strong>JavaScript</strong>
</p>
Если получить текст через:
range.toString();
мы получим: Hello JavaScript. Вся внутренняя структура будет потеряна, потому что результатом является просто строка. Если нужно сохранить HTML-узлы внутри выделенного участка, используется cloneContents(). Этот метод создаёт копию выбранного фрагмента в виде DocumentFragment, сохраняя вложенные элементы:
const fragment = range.cloneContents();

document.body.appendChild(fragment);
Теперь вместе с текстом сохранится и структура:
<strong>JavaScript</strong>
Range можно не только получать из пользовательского выделения, но и создавать вручную. Например, можно программно выделить всё содержимое определённого элемента:
const element = document.querySelector('#editor');

const range = document.createRange();

range.selectNodeContents(element);
Теперь диапазон знает, какой фрагмент DOM нужно выделить. Остаётся передать его в объект Selection, чтобы браузер показал это выделение пользователю:
const selection = window.getSelection();

selection.removeAllRanges();
selection.addRange(range);
После выполнения браузер выделит всё содержимое элемента. Но Range нужен не только для чтения выделений. С его помощью можно изменять DOM в конкретной позиции. Например, заменить выделенный пользователем текст:
const range = window
  .getSelection()
  .getRangeAt(0);

const span = document.createElement('span');

span.textContent = 'Новый текст';

range.deleteContents();

range.insertNode(span);
Сначала deleteContents() удаляет выбранный фрагмент, а затем insertNode() вставляет новый элемент точно туда, где находился диапазон. Это особенно полезно в редакторах текста, где нужно сохранить структуру документа и позицию изменения. Есть ещё один похожий метод — extractContents(). В отличие от cloneContents(), который создаёт копию, extractContents() забирает содержимое из DOM и удаляет его с текущего места:
const fragment = range.extractContents();
Полученный DocumentFragment можно затем вставить в другой участок документа. Range API используется внутри rich text редакторов, систем подсветки поиска, комментариев и любых интерфейсов, где требуется работать с отдельными частями документа. 🔥 Range API — инструмент для точной работы с фрагментами DOM: выделять, копировать, извлекать, удалять и заменять части документа без полной пересборки элемента. 📣 Code Ready | #практика

41% кода уже пишет AI. Пора научиться использовать это в свою пользу Пока одни всё ещё учат синтаксис, другие собирают рабочи
41% кода уже пишет AI. Пора научиться использовать это в свою пользу Пока одни всё ещё учат синтаксис, другие собирают рабочие продукты с помощью Claude Code и AI. Хекслет проведёт бесплатный воркшоп, где за один вечер вы создадите собственного Telegram-бота для изучения английского. На практике покажут, как: • работать с Claude Code; • подключать Gemini API; • создавать AI, который сам генерирует уроки; • запускать полноценные продукты без месяцев разработки. В результате у вас останется готовый Telegram-бот, которого можно использовать самому или развивать дальше. 28 июля, 19:00 (мск) Бесплатное участие. Зарегистрироваться -> #реклама О рекламодателе

📱 Осваиваем регулярные выражения! Эта шпаргалка по ключевым приёмам работы с RegExp: квантификаторы, группы, классы символов
+4
📱 Осваиваем регулярные выражения! Эта шпаргалка по ключевым приёмам работы с RegExp: квантификаторы, группы, классы символов, флаги и проверки начала или конца строки. Подойдёт для валидации данных, парсинга текста и оптимизации поиска. 📣 Code Ready | #шпора

👩‍💻 Один тег чтобы обернуть секцию с поиском или фильтром! Тег используется для обозначения секции страницы, которая содерж
👩‍💻 Один тег чтобы обернуть секцию с поиском или фильтром! Тег <search> используется для обозначения секции страницы, которая содержит поиск или элементы фильтрации. Он помогает браузерам, поисковым системам и вспомогательным технологиям лучше понимать структуру страницы. Использовать <search> можно для: • формы поиска по сайту; • фильтров каталога; • панели поиска по таблицам или спискам; • блока с настройками фильтрации. Важно: тег относительно новый, поэтому поддержка в некоторых браузерах и вспомогательных технологиях пока развивается. При необходимости можно дополнительно использовать role="search". 📣 Code Ready | #атрибут

Element.animate() — управление композицией анимаций в браузере! CSS-анимации удобны, пока элемент имеет одно состояние. Но когда несколько эффектов должны управляться из JavaScript, Web Animations API даёт больше контроля. Например, несколько анимаций одного элемента могут существовать одновременно:
const fade = element.animate(
  [
    { opacity: 0 },
    { opacity: 1 }
  ],
  {
    duration: 300
  }
);

const move = element.animate(
  [
    { transform: 'translateY(20px)' },
    { transform: 'translateY(0)' }
  ],
  {
    duration: 300
  }
);
Браузер создаёт отдельные Animation-объекты и объединяет их эффекты при расчёте итогового стиля элемента. У каждой анимации есть собственное состояние:
console.log(fade.playState);

console.log(move.currentTime);
currentTime позволяет управлять прогрессом вручную:
fade.currentTime = 150;
Анимация сразу перейдёт примерно к середине выполнения. Это полезно для синхронизации анимаций с внешним состоянием, например с прогрессом загрузки:
animation.currentTime =
  progress * animation.effect.getTiming().duration;
Также Web Animations API позволяет изменять параметры уже созданного эффекта:
animation.effect.updateTiming({
  duration: 1000
});
При этом не нужно пересоздавать анимацию. Отдельно стоит учитывать композицию свойств. Если два эффекта изменяют один и тот же параметр:
element.animate(
  [
    { transform: 'translateX(100px)' }
  ],
  {
    duration: 1000
  }
);

element.animate(
  [
    { transform: 'scale(1.2)' }
  ],
  {
    duration: 1000
  }
);
Оба эффекта работают с одним CSS-свойством transform. Итоговое поведение зависит от правил композиции анимаций, поэтому параллельное изменение одного свойства может дать неожиданный результат. Для сложных случаев можно управлять композицией через composite:
element.animate(
  [
    {
      transform: 'translateX(100px)'
    }
  ],
  {
    duration: 500,
    composite: 'add'
  }
);
В этом режиме новое значение добавляется к существующему, а не заменяет его. 🔥 Element.animate() — это не просто замена CSS keyframes. Web Animations API предоставляет полноценную модель управления анимациями: состояние, время выполнения, изменение параметров и правила композиции эффектов. 📣 Code Ready | #практика

На Stepik запустили курс по вайбкодингу c Claude Code Первым делом вы освоите базу Claude Code и научитесь проектировать полн
На Stepik запустили курс по вайбкодингу c Claude Code Первым делом вы освоите базу Claude Code и научитесь проектировать полноценные приложения. После этого перейдёте к более продвинутым инструментам и автоматизации: ➡️Разработаете собственные MCP-серверы и Claude Skills ➡️Автоматизируете разработку с помощью Agent Loops и хуков ➡️Освоите Claude Design, Cowork и Connectors ➡️Построите личную систему знаний на базе Obsidian + Claude Cowork ➡️Научитесь работать с таблицами при помощи Cowork ➡️Перестанете постоянно упираться в лимиты Claude А в финале получите готовую дорожную карту, полезные лайфхаки и 7 практических способов обхода блокировок Claude Code в России. 🔥 В течении 48 часов действует скидка 25%

Наткнулся на необычную и очень интересную статью на Хабре: «PowerHTML»! В этой статье: • Показывается, как создать интерактив
Наткнулся на необычную и очень интересную статью на Хабре: «PowerHTML»! В этой статье: • Показывается, как создать интерактивные презентации, которые работают полностью офлайн в одном HTML-файле без установки программ и регистрации; • Разбираются возможности редактора: встроенные видео, анимации, таймеры, интерактивные элементы и др; • Объясняется, как с помощью AI был создан полноценный инструмент, ориентированный на преподавателей, спикеров и всех, кто проводит презентации. 🔊 Продолжайте читать на Habr! 📣 Code Ready | #статья

Intl.ListFormat: форматируем списки с учётом языка пользователя! При разработке интерфейсов часто нужно вывести набор данных в виде обычного текста: участников команды, выбранные фильтры, категории товара или список доступных вариантов. Самый простой вариант — использовать join():
const users = [
  'Alex',
  'Maria',
  'John'
];

users.join(', ');
Такой подход работает только для простого разделения элементов. Но он не знает правил конкретного языка. В английском между последними элементами используется and, в русском — и, а в других локалях могут быть свои правила форматирования. Если приложение поддерживает несколько языков, обычно появляются ручные проверки:
if (locale === 'en') {
  // добавить and
}

if (locale === 'ru') {
  // добавить и
}
Поддерживать такую логику сложно, поэтому для подобных задач в JavaScript существует стандартный API Intl.ListFormat. Создаём форматтер и передаём нужную локаль:
const formatter =
  new Intl.ListFormat('ru');

formatter.format([
  'JavaScript',
  'TypeScript',
  'Python'
]);
Результат: JavaScript, TypeScript и Python. При изменении локали правила форматирования изменятся автоматически:
const formatter =
  new Intl.ListFormat('en');

formatter.format([
  'JavaScript',
  'TypeScript',
  'Python'
]);
Результат: JavaScript, TypeScript, and Python. Intl.ListFormat использует встроенные правила локализации JavaScript, поэтому не нужно самостоятельно реализовывать союзы, разделители и особенности разных языков. Кроме обычного перечисления можно форматировать варианты выбора. Например, когда пользователь выбирает один из способов оплаты:
const formatter =
  new Intl.ListFormat(
    'ru',
    {
      type: 'disjunction'
    }
  );

formatter.format([
  'Карта',
  'PayPal',
  'Перевод'
]);
Результат: Карта, PayPal или Перевод. По умолчанию используется conjunction — обычное перечисление через союз "и". Значение disjunction используется для альтернатив через "или". Также важно понимать, что Intl.ListFormat не изменяет исходные данные. Он только создаёт новую строку:
const tags = [
  'Frontend',
  'Backend',
  'DevOps'
];

const text =
  new Intl.ListFormat('ru')
    .format(tags);
Массив tags останется без изменений, что удобно при работе с состоянием приложения и неизменяемыми данными. В реальных проектах этот API полезен для отображения пользователей, тегов, фильтров, категорий и любых списков, которые должны выглядеть естественно для пользователей из разных стран. 🔥 Intl.ListFormat позволяет использовать стандартные правила локализации JavaScript вместо ручной сборки строк через join() и множества условий для разных языков. 📣 Code Ready | #практика