Headless WordPress на Next.js и GraphQL: отдаем контент через API, рендерим на Edge
WordPress держит 43% веба, хотя backend-разработчики критикуют его за экосистему плагинов и функциональный стиль. Отрываем админку от UI: оставляем WP как CMS для редакторов, а фронт переносим на Next.js. Редакторы остаются в привычной админке, а вы получаете React с SSR и статической генерацией.
GraphQL служит связующим слоем. WordPress отдает контент через API, а Next.js забирает его на этапе сборки или по запросу. Cloudflare Pages раздает результат из ближайшего edge, и latency перестает зависеть от хостинга базы данных.
Если мигрируете легаси или строите новый проект с контентной нагрузкой, стоит разобрать, как стыкуются слои и где подстерегают подводные камни с кешированием запросов.
@tproger_web
Читайте также в VK и Max
WordPress держит 43% веба, хотя backend-разработчики критикуют его за экосистему плагинов и функциональный стиль. Отрываем админку от UI: оставляем WP как CMS для редакторов, а фронт переносим на Next.js. Редакторы остаются в привычной админке, а вы получаете React с SSR и статической генерацией.
GraphQL служит связующим слоем. WordPress отдает контент через API, а Next.js забирает его на этапе сборки или по запросу. Cloudflare Pages раздает результат из ближайшего edge, и latency перестает зависеть от хостинга базы данных.
Если мигрируете легаси или строите новый проект с контентной нагрузкой, стоит разобрать, как стыкуются слои и где подстерегают подводные камни с кешированием запросов.
@tproger_web
Читайте также в VK и Max
👍3❤2
Scroll-анимации на CSS, когда JavaScript уже не нужен
Scroll-эффекты до сих пор часто пишут через обработчики события прокрутки, хотя браузер давно лучше понимает, где находится пользователь. Новые CSS scroll features позволяют собирать продвинутые анимации декларативно и не гонять JS на каждом движении страницы.
В туториале Web Dev Simplified показывают, как использовать эти возможности для красивых scroll-driven эффектов, а рядом дают готовый код на GitHub. Это хороший материал для интерфейсов, где хочется движения, но не хочется тащить тяжёлую анимационную логику.
Если у вас есть лендинг, документация или интерактивная витрина, стоит разобрать пример. Детали помогут понять, где CSS закрывает задачу чище, чем очередной scroll listener.
@tproger_web
Читайте также в VK и Max
Scroll-эффекты до сих пор часто пишут через обработчики события прокрутки, хотя браузер давно лучше понимает, где находится пользователь. Новые CSS scroll features позволяют собирать продвинутые анимации декларативно и не гонять JS на каждом движении страницы.
В туториале Web Dev Simplified показывают, как использовать эти возможности для красивых scroll-driven эффектов, а рядом дают готовый код на GitHub. Это хороший материал для интерфейсов, где хочется движения, но не хочется тащить тяжёлую анимационную логику.
Если у вас есть лендинг, документация или интерактивная витрина, стоит разобрать пример. Детали помогут понять, где CSS закрывает задачу чище, чем очередной scroll listener.
@tproger_web
Читайте также в VK и Max
❤7👍4
Фокус-кольцо, которое летает между элементами без ручной геометрии
Клавиатурная навигация часто выглядит как формальность: outline есть, но взгляд всё равно теряет, куда перескочил фокус. Новая игрушка с View Transitions показывает, как сделать «flying focus» без постоянного измерения DOM через
Идея такая: у focused-элементов есть дочерний
Можно посмотреть реализацию и ограничения. В деталях полезен сам паттерн: дать браузеру анимировать переход, а не считать координаты вручную.
@tproger_web
Читайте также в VK и Max
Клавиатурная навигация часто выглядит как формальность: outline есть, но взгляд всё равно теряет, куда перескочил фокус. Новая игрушка с View Transitions показывает, как сделать «flying focus» без постоянного измерения DOM через
getBoundingClientRect().Идея такая: у focused-элементов есть дочерний
span с одинаковым view-transition-name. При переходе фокуса браузер сам анимирует кольцо между состояниями. Автор отдельно проговаривает важный момент: уважать prefers-reduced-motion, потому что доступность не должна превращаться в аттракцион.Можно посмотреть реализацию и ограничения. В деталях полезен сам паттерн: дать браузеру анимировать переход, а не считать координаты вручную.
@tproger_web
Читайте также в VK и Max
❤3
JavaScript 2026: что учить, когда язык снова разросся
Проблема современного JS не в том, что «всё поменялось», а в том, что вокруг языка стало много слоёв: рантаймы, метафреймворки, RSC, сборщики, npm-безопасность и AI-инструменты. Поэтому полезно иногда собрать карту, где язык, а где экосистема.
В обзоре Frontend Masters есть
Можно разобрать карту и выбрать, что влияет на ваш стек. В деталях особенно полезны примеры, где новая возможность убирает старый самописный код.
@tproger_web
Читайте также в VK и Max
Проблема современного JS не в том, что «всё поменялось», а в том, что вокруг языка стало много слоёв: рантаймы, метафреймворки, RSC, сборщики, npm-безопасность и AI-инструменты. Поэтому полезно иногда собрать карту, где язык, а где экосистема.
В обзоре Frontend Masters есть
RegExp.escape(), explicit resource management через using, Array.fromAsync, Iterator helpers, Next.js 16, React 19, Turbopack и боль npm supply chain. Хороший формат для тех, кто хочет понять приоритеты, а не читать чейнджлоги пачками.Можно разобрать карту и выбрать, что влияет на ваш стек. В деталях особенно полезны примеры, где новая возможность убирает старый самописный код.
@tproger_web
Читайте также в VK и Max
👍4❤3
Если вы устали от бесконечных тасок и созвонов, то мы приготовили для вас игру, которая поможет отдохнуть
А заодно проверить вашу способность быстро запоминать новую инфу. Переходите по ссылке и играйте в нашу «Меморину». И делитесь результатами в комментариях!
Играть тут: https://tprg.ru/jB9F
@tproger_web
Читайте также в VK и Max
А заодно проверить вашу способность быстро запоминать новую инфу. Переходите по ссылке и играйте в нашу «Меморину». И делитесь результатами в комментариях!
Играть тут: https://tprg.ru/jB9F
@tproger_web
Читайте также в VK и Max
❤5🔥5👍3👎3
Все современные браузеры позволяют сайту следить за вашими вкладками через SSD
Атака FROST использует Origin Private File System, API без запроса разрешений, доступное в Chromium, Firefox и Safari. Сайт создаёт в OPFS файл от 1 ГБ и измеряет задержки случайных чтений. Когда другая вкладка или приложение обращается к SSD, задержки меняются, и свёрточная нейросеть по сигнатуре определяет, что именно у вас открыто.
Полная атака продемонстрирована на Mac с M2, на Linux подтверждён базовый примитив. Windows в тестах не участвовала, но авторы не исключают, что техника сработает и там. Пока случаев применения в реальности не зафиксировано, и единственная защита пока что закрывать неиспользуемые вкладки.
Подробности о FROST.
Атака FROST использует Origin Private File System, API без запроса разрешений, доступное в Chromium, Firefox и Safari. Сайт создаёт в OPFS файл от 1 ГБ и измеряет задержки случайных чтений. Когда другая вкладка или приложение обращается к SSD, задержки меняются, и свёрточная нейросеть по сигнатуре определяет, что именно у вас открыто.
Полная атака продемонстрирована на Mac с M2, на Linux подтверждён базовый примитив. Windows в тестах не участвовала, но авторы не исключают, что техника сработает и там. Пока случаев применения в реальности не зафиксировано, и единственная защита пока что закрывать неиспользуемые вкладки.
Подробности о FROST.
🤣7👍1🫡1
CDATA в RSS кажется удобным, пока вы не столкнётесь с
В RSS и Atom CDATA берут, чтобы не экранировать HTML и спецсимволы вручную. Проблема в том, что последовательность
При этом CDATA не делает содержимое «безопаснее» — XML-парсер выдаёт точно такой же текст, как при обычном экранировании. Вывод получается разнородным: где-то один блок, где-то несколько склеенных. А отладка превращается в головоломку, если контент сам оказывается про CDATA.
Проще сразу сериализовать XML корректно и избавиться от лишнего edge case в коде генерации фида.
]]> внутри контентаВ RSS и Atom CDATA берут, чтобы не экранировать HTML и спецсимволы вручную. Проблема в том, что последовательность
]]>, закрывающая блок, не может быть экранирована внутри него. Приходится разбивать CDATA на куски, что сразу ломает всю простоту подхода.При этом CDATA не делает содержимое «безопаснее» — XML-парсер выдаёт точно такой же текст, как при обычном экранировании. Вывод получается разнородным: где-то один блок, где-то несколько склеенных. А отладка превращается в головоломку, если контент сам оказывается про CDATA.
Проще сразу сериализовать XML корректно и избавиться от лишнего edge case в коде генерации фида.
❤3
Chrome пробует частичные обновления прямо в HTML
HTML снова пытается стать самостоятельнее. В Chrome тестируют Declarative Partial Updates:
Практический смысл простой: часть того, что сейчас делается через JS-слой или фреймворк, можно будет отдавать как поток HTML и подставлять по готовности. Для островной архитектуры, тяжёлых блоков и SPA-обновлений это очень интересный сигнал.
Пока это эксперимент: Chrome 148 с флагом, есть polyfill, ограничения тоже есть.
HTML снова пытается стать самостоятельнее. В Chrome тестируют Declarative Partial Updates:
template for может заменить заранее оставленный маркер в документе, а новые streaming-методы — дописывать HTML в уже существующий узел.Практический смысл простой: часть того, что сейчас делается через JS-слой или фреймворк, можно будет отдавать как поток HTML и подставлять по готовности. Для островной архитектуры, тяжёлых блоков и SPA-обновлений это очень интересный сигнал.
Пока это эксперимент: Chrome 148 с флагом, есть polyfill, ограничения тоже есть.
👍13🔥6🤔2🗿1
MDN показали, как разгрузили фронтенд после редизайна
Не знаю, обратили ли вы внимание, но у MDN изменился не только дизайн. Интереснее то, что случилось под капотом: команда рассказала, как Markdown превращается в HTML и JSON, компоненты рендерятся на сервере, а на клиент уезжает только тот JS/CSS, который нужен конкретной странице.
Ставка на Web Components и Declarative Shadow DOM здесь понятна: документация быстрее грузится и не тащит лишний runtime.
Рекомендую почитать всем, кто делает большие контентные сайты. Можно взять из их опыта пару решений или собрать себе чеклист для следующего рефакторинга.
Не знаю, обратили ли вы внимание, но у MDN изменился не только дизайн. Интереснее то, что случилось под капотом: команда рассказала, как Markdown превращается в HTML и JSON, компоненты рендерятся на сервере, а на клиент уезжает только тот JS/CSS, который нужен конкретной странице.
Ставка на Web Components и Declarative Shadow DOM здесь понятна: документация быстрее грузится и не тащит лишний runtime.
Рекомендую почитать всем, кто делает большие контентные сайты. Можно взять из их опыта пару решений или собрать себе чеклист для следующего рефакторинга.
🔥7
DOM и canvas наконец-то пытаются подружить
Canvas хорош, пока вам нужна только графика. Как только появляются кнопки, формы, выделение текста, accessibility и нормальное поведение браузера, начинается второй фронтенд поверх первого. Все, кто делал редакторы, 3D-интерфейсы или игры в браузере, понимают боль.
HTML-in-Canvas API предлагает интересный компромисс: DOM-элементы можно рисовать в 2D canvas или WebGL/WebGPU texture, но сохранять интерактивность и браузерные возможности. То есть UI остаётся HTML, а жить может внутри canvas-сцены.
Пока это origin trial так что в прод не несём. Но идею я бы сохранил: если взлетит, часть canvas-костылей станет не нужна.
Canvas хорош, пока вам нужна только графика. Как только появляются кнопки, формы, выделение текста, accessibility и нормальное поведение браузера, начинается второй фронтенд поверх первого. Все, кто делал редакторы, 3D-интерфейсы или игры в браузере, понимают боль.
HTML-in-Canvas API предлагает интересный компромисс: DOM-элементы можно рисовать в 2D canvas или WebGL/WebGPU texture, но сохранять интерактивность и браузерные возможности. То есть UI остаётся HTML, а жить может внутри canvas-сцены.
Пока это origin trial так что в прод не несём. Но идею я бы сохранил: если взлетит, часть canvas-костылей станет не нужна.
❤6🤔4
Oxlint — линтер на Rust, который в 50–100 раз быстрее ESLint и работает сразу после установки
Если проверка кода в вашем проекте растягивается на минуты, я бы присмотрелся к Oxlint. Это рабочий инструмент из экосистемы Oxc от VoidZero: 107 правил из коробки, конфигурировать ничего не нужно.
В репозитории Vue Core Oxlint справляется за 1,3 секунды против 133,8 у ESLint с typescript-eslint: почти в сотню раз быстрее. Для React Router: 435 мс против 29,5 с. Проверка с учётом типов при этом не требует полного прогона компилятора tsc.
Поддержка ESLint-плагинов пока экспериментальная, так что если проект завязан на редкие кастомные правила, я бы запустил оба линтера параллельно и мигрировал постепенно. Когда миграция оправдана, читайте в материале.
Если проверка кода в вашем проекте растягивается на минуты, я бы присмотрелся к Oxlint. Это рабочий инструмент из экосистемы Oxc от VoidZero: 107 правил из коробки, конфигурировать ничего не нужно.
В репозитории Vue Core Oxlint справляется за 1,3 секунды против 133,8 у ESLint с typescript-eslint: почти в сотню раз быстрее. Для React Router: 435 мс против 29,5 с. Проверка с учётом типов при этом не требует полного прогона компилятора tsc.
Поддержка ESLint-плагинов пока экспериментальная, так что если проект завязан на редкие кастомные правила, я бы запустил оба линтера параллельно и мигрировал постепенно. Когда миграция оправдана, читайте в материале.
❤3🔥3👍1
TypeScript иногда выбирает тип, который кажется нелогичным. Вот почему
В TypeScript дженерики обычно работают интуитивно, пока внезапно не выдают
Если пишете типизированные библиотеки или просто хотите понять, почему компилятор ведёт себя именно так, я бы сохранил на тот случай, когда очередной неожиданный вывод типов застанет врасплох и придётся объяснять команде, почему ваш код компилируется совсем не так, как вы предполагали.
В TypeScript дженерики обычно работают интуитивно, пока внезапно не выдают
unknown вместо ожидаемого пересечения или сворачивают объединение обобщённых типов не туда. Автор разбирает механику, которая стоит за этими сюрпризами: как компилятор выбирает кандидатов для типовых переменных, почему один аргумент может доминировать над другим и когда inference ломает интуицию.Если пишете типизированные библиотеки или просто хотите понять, почему компилятор ведёт себя именно так, я бы сохранил на тот случай, когда очередной неожиданный вывод типов застанет врасплох и придётся объяснять команде, почему ваш код компилируется совсем не так, как вы предполагали.
❤5
Forwarded from Типичный программист
Форма регистрации начинается не с полей и кнопки
Можно собрать красивую онлайн-регистрацию на тысячу человек, привязать базу, письма и сверку сотрудников. А потом HR пришлёт регламент и спросит: где лежат персональные данные, кто имеет доступ, что с HTTPS, ФЗ-152 и планом на случай утечки.
Вот тут внезапно оказывается, что главная сложность не в форме. Код работает, письма уходят, но проект всё равно может упереться в ответственность и процессы: лишний аккаунт в базе, серверы не там, согласие пользователя забыли.
В свежем разборе на Tproger это превращается в чеклист вопросов, которые лучше задать себе до того, как первый гость оставит телефон и почту.
Можно собрать красивую онлайн-регистрацию на тысячу человек, привязать базу, письма и сверку сотрудников. А потом HR пришлёт регламент и спросит: где лежат персональные данные, кто имеет доступ, что с HTTPS, ФЗ-152 и планом на случай утечки.
Вот тут внезапно оказывается, что главная сложность не в форме. Код работает, письма уходят, но проект всё равно может упереться в ответственность и процессы: лишний аккаунт в базе, серверы не там, согласие пользователя забыли.
В свежем разборе на Tproger это превращается в чеклист вопросов, которые лучше задать себе до того, как первый гость оставит телефон и почту.
💩5🔥2
@counter-style: CSS-генератор текста, который многие игнорируют
Я бы сохранил этот трюк: at-rule
Практический сценарий: замаскировать текст символьной лапшой прямо в CSS. Или собрать ротатор слов, где счётчик сам подбирает вариант из заданного набора. Для декоративных задач это избавляет от ручной сборки последовательности, а @counter-style всё делает сам. Frontend Masters показывают, как это устроено.
Я бы сохранил этот трюк: at-rule
@counter-style работает не только с маркерами списка, но и как полноценный генератор строк через CSS counter. По умолчанию там system: symbolic — символы зацикливаются и умножаются по мере роста счётчика.Практический сценарий: замаскировать текст символьной лапшой прямо в CSS. Или собрать ротатор слов, где счётчик сам подбирает вариант из заданного набора. Для декоративных задач это избавляет от ручной сборки последовательности, а @counter-style всё делает сам. Frontend Masters показывают, как это устроено.
❤2
Почему TypeScript иногда выводит не тот тип: разбор алгоритма
Казалось бы, вывод типов — базовая механика компилятора. Но в двухфазном алгоритме TypeScript есть ловушки, которые ловят даже опытных разработчиков: компилятор сначала собирает кандидатов из ковариантных и контравариантных позиций, а потом сворачивает их в единственный тип. При этом контравариантный результат обычно побеждает, а общий супертип никогда не выходит за рамки списка кандидатов.
В материале разбирают, почему пересечения типов ведут себя непредсказуемо, почему условные типы внутри generic-контекста не вычисляются и как
Сохраните, если пишете API со значениями по умолчанию или ловили странный unknown там, где ждали конкретный тип.
Казалось бы, вывод типов — базовая механика компилятора. Но в двухфазном алгоритме TypeScript есть ловушки, которые ловят даже опытных разработчиков: компилятор сначала собирает кандидатов из ковариантных и контравариантных позиций, а потом сворачивает их в единственный тип. При этом контравариантный результат обычно побеждает, а общий супертип никогда не выходит за рамки списка кандидатов.
В материале разбирают, почему пересечения типов ведут себя непредсказуемо, почему условные типы внутри generic-контекста не вычисляются и как
NoInfer<T> с TypeScript 5.4+ блокирует вывод из конкретной позиции.Сохраните, если пишете API со значениями по умолчанию или ловили странный unknown там, где ждали конкретный тип.
❤2
Zero 1.0: веб-приложение читает данные локально, а сервер догоняет потом
Если интерфейс ждёт каждый запрос к серверу, загрузка становится частью дизайна. Zero предлагает другой подход: приложение читает данные из локального кэша, а сервер синхронизируется в фоне.
Под капотом —
Пока только Postgres, SSR ещё в roadmap, а клиентский слой добавляет вес и сложность. Зато как идея для интерфейсов без вечного ожидания сети — очень сильная.
Если интерфейс ждёт каждый запрос к серверу, загрузка становится частью дизайна. Zero предлагает другой подход: приложение читает данные из локального кэша, а сервер синхронизируется в фоне.
Под капотом —
zero-client в приложении, zero-cache рядом с сервером и read-only реплика Postgres. Запросы пишутся на ZQL, выполняются локально и возвращают результат почти сразу, а авторитетные данные доезжают асинхронно.Пока только Postgres, SSR ещё в roadmap, а клиентский слой добавляет вес и сложность. Зато как идея для интерфейсов без вечного ожидания сети — очень сильная.
zero.rocicorp.dev
Zero 1.0
First Stable Release
👍3🤔3❤2
3D на CSS, когда canvas и WebGL остались за дверью
Оказывается, DOM ещё не всё сказал в теме странных визуальных экспериментов. PolyCSS рендерит текстурированные 3D-меши обычными HTML-элементами: каждый полигон — отдельный DOM-узел, а положение задаётся через
Практической замены Three.js тут, конечно, нет. Зато есть интересный трюк: элементы остаются частью DOM, их можно стилизовать CSS, делать интерактивными и трогать привычными веб-инструментами. Для прототипов и демо самое то.
https://polycss.com/
Оказывается, DOM ещё не всё сказал в теме странных визуальных экспериментов. PolyCSS рендерит текстурированные 3D-меши обычными HTML-элементами: каждый полигон — отдельный DOM-узел, а положение задаётся через
matrix3d().Практической замены Three.js тут, конечно, нет. Зато есть интересный трюк: элементы остаются частью DOM, их можно стилизовать CSS, делать интерактивными и трогать привычными веб-инструментами. Для прототипов и демо самое то.
https://polycss.com/
🤔4👍2👎1