[{"data":1,"prerenderedAt":235},["ShallowReactive",2],{"project-ru-visual-storefront":3,"recommendation-mention-sources":174},{"id":4,"title":5,"body":6,"category":130,"context":131,"cover":132,"coverAlt":133,"demo":134,"description":135,"extension":136,"featured":137,"locale":138,"meta":139,"navigation":140,"order":117,"path":141,"published":140,"repository":134,"results":142,"role":152,"seo":153,"slug":154,"stack":155,"stem":171,"year":172,"__hash__":173},"projects\u002Fru\u002Fprojects\u002Fvisual-storefront.md","Редизайн визуального редактора сайта inSales",{"type":7,"value":8,"toc":115},"minimark",[9,14,18,21,28,34,38,41,45,50,53,57,60,64,67,71,74,78,81,84,90,95,99],[10,11,13],"h2",{"id":12},"задача","Задача",[15,16,17],"p",{},"Визуальный редактор — основной инструмент, через который продавцы на inSales меняют дизайн, страницы и виджеты своего магазина. Сам магазин открывается в iframe внутри админки, а редактор управляет им снаружи.",[15,19,20],{},"До редизайна рядом с iframe постоянно висел большой сайдбар, и в нём было всё сразу: общие настройки дизайна, секции страницы, списки виджетов и настройки выбранного виджета. Добавить, изменить или удалить виджет можно было и из сайдбара, и прямо в предпросмотре, поэтому понятного основного способа не было. Сайдбар забирал ширину у самого сайта, а онбординг пришлось бы строить на переключении уровней одной и той же панели.",[15,22,23],{},[24,25],"img",{"alt":26,"src":27},"Старый редактор: постоянный сайдбар с настройками дизайна и разделами страниц рядом с магазином","\u002Fimages\u002Fwork\u002Fvisual-storefront\u002Fold-editor-permanent-sidebar.webp",[15,29,30],{},[31,32,33],"em",{},"Так было: общие настройки, секции и списки виджетов в одной панели, которая не закрывается.",[10,35,37],{"id":36},"моя-роль","Моя роль",[15,39,40],{},"Макет нарисовал дизайнер. Я был единственным frontend-разработчиком и за восемь недель реализовал его целиком: структуру интерфейса, загрузку данных, поведение iframe и онбординг из восьми шагов. Новый контракт данных прорабатывал вместе с backend. Технический режим предложил сам: в макете этого сценария не было.",[10,42,44],{"id":43},"что-я-сделал","Что я сделал",[46,47,49],"h3",{"id":48},"у-каждой-части-экрана-своя-роль","У каждой части экрана своя роль",[15,51,52],{},"Общие настройки дизайна и навигация по страницам переехали в верхнее меню. Действия с виджетом остались в предпросмотре. По кнопке «Редактировать» открывается плавающая панель только с настройками этого виджета. Панель я написал отдельным компонентом и перенёс в неё рендеринг настроек. Она открывается поверх сайта и не сдвигает его, ставится слева или справа и прячется, когда пользователь закончил или начал скроллить. Пока она открыта, поверх iframe лежит оверлей: случайный клик по ссылке внутри виджета не уведёт магазин на другую страницу посреди редактирования.",[46,54,56],{"id":55},"данные-загружаются-когда-они-нужны-интерфейсу","Данные загружаются, когда они нужны интерфейсу",[15,58,59],{},"Старый редактор при открытии одним запросом забирал дизайн, лейауты и все списки виджетов, потому что сайдбар показывал их сразу. Ответ весил всего 5–10 КБ, так что ускорения здесь не было. Смысл был в другом: API должен соответствовать новому экрану. Теперь при старте редактор запрашивает только данные для верхнего меню, а списки виджетов — когда пользователь их открывает.",[46,61,63],{"id":62},"переключение-страниц-держит-редактор-и-магазин-в-одном-состоянии","Переключение страниц держит редактор и магазин в одном состоянии",[15,65,66],{},"При выборе страницы в меню iframe должен перейти на неё, редактор — определить активный лейаут и загрузить его настройки, а следующие изменения — попасть именно в эту страницу. Кроме стандартных шаблонов (товар, категория, блог, личный кабинет и другие) продавец может сделать отдельную страницу, например баннер только в одной категории. Такие страницы тоже должны были появляться в меню и правильно открываться, поэтому навигация не могла быть фиксированным списком.",[46,68,70],{"id":69},"доступ-к-виджетам-которых-не-видно-на-странице","Доступ к виджетам, которых не видно на странице",[15,72,73],{},"Форма предзаказа, обратная связь и всплывающие окна появляются только после действия покупателя. Когда сайдбар убрали, а управление перенесли в предпросмотр, до них стало бы не добраться. Я добавил в верхнее меню отдельный раздел, где их можно найти, добавить и настроить.",[46,75,77],{"id":76},"технический-режим-который-не-зависит-от-iframe","Технический режим, который не зависит от iframe",[15,79,80],{},"Продавцы и их разработчики пишут в виджетах собственный HTML, CSS, JavaScript и Liquid. Критическая ошибка в таком коде может не дать магазину загрузиться. В новом дизайне все кнопки управления виджетами находились внутри этого магазина, и сломанная страница прятала бы как раз тот виджет, который её сломал. Обходной путь — искать виджет в другом разделе админки или перезаливать шаблон.",[15,82,83],{},"Я предложил и сделал технический режим. Если редактор видит, что страница не загрузилась, он предлагает открыть список всех виджетов страницы с названиями и идентификаторами. Оттуда продавец или сотрудник поддержки открывает настройки, правит код или удаляет виджет. На рабочей странице этот список тоже пригодится: так быстрее найти нужный блок.",[15,85,86],{},[24,87],{"alt":88,"src":89},"Список виджетов страницы по секциям с действиями «Код виджета», «Настройки виджета» и «Удалить виджет»","\u002Fimages\u002Fwork\u002Fvisual-storefront\u002Frecovery-mode-widget-list.webp",[15,91,92],{},[31,93,94],{},"Список работает без предпросмотра, поэтому сломанный виджет можно исправить или удалить.",[10,96,98],{"id":97},"результат","Результат",[100,101,102,106,109,112],"ul",{},[103,104,105],"li",{},"Новым редактором пользуются больше 90% магазинов inSales, для шаблонов актуального поколения он стандартный. Старый остался только для шаблонов, сделанных до 2020 года.",[103,107,108],{},"Доля новых пользователей, которые в первой сессии сами изменили настройку шаблона или виджета и сохранили результат, выросла с 60% до 80%, то есть на 20 процентных пунктов.",[103,110,111],{},"При закрытых панелях предпросмотр сайта на экране 1920 px стал примерно на 17% шире.",[103,113,114],{},"Технический режим работает в продакшене: если код виджета ломает страницу, продавец или поддержка чинят её прямо из редактора.",{"title":116,"searchDepth":117,"depth":117,"links":118},"",2,[119,120,121,129],{"id":12,"depth":117,"text":13},{"id":36,"depth":117,"text":37},{"id":43,"depth":117,"text":44,"children":122},[123,125,126,127,128],{"id":48,"depth":124,"text":49},3,{"id":55,"depth":124,"text":56},{"id":62,"depth":124,"text":63},{"id":69,"depth":124,"text":70},{"id":76,"depth":124,"text":77},{"id":97,"depth":117,"text":98},"Браузерные редакторы","inSales","\u002Fimages\u002Fwork\u002Fvisual-storefront\u002Ffloating-widget-settings.webp","Новый визуальный редактор inSales: плавающая панель настроек промо-слайдера поверх предпросмотра магазина во всю ширину",null,"Сделал frontend нового визуального редактора, которым пользуются больше 90% магазинов inSales, и добавил технический режим для страниц, сломанных кодом виджета.","md",false,"ru",{},true,"\u002Fru\u002Fprojects\u002Fvisual-storefront",[143,146,149],{"value":144,"label":145},"90%+","магазинов inSales работают в новом редакторе",{"value":147,"label":148},"60% → 80%","новых пользователей сами изменили и сохранили настройку шаблона или виджета в первой сессии",{"value":150,"label":151},"≈17%","шире предпросмотр сайта на экране 1920 px при закрытых панелях","Единственный frontend-разработчик: редизайн, контракт данных, технический режим",{"title":5,"description":135},"visual-storefront",[156,157,158,159,160,161,162,163,164,165,166,167,168,169,170],"Vue.js","TypeScript","Complex UI","Front-End Development","Frontend Architecture","JavaScript","SCSS","Vuetify","Mixpanel","API Integration","State Management","Web Application Development","E-Commerce Development","Customer Onboarding","E-commerce Optimization","ru\u002Fprojects\u002Fvisual-storefront","Май – август 2024","BPxMiQgXjsInfjNk7IzAyx6wcVXPqgaa20yWMdScHVo",[175,186,191,205,215,220,225,230],{"stem":176,"name":177,"date":178,"featured":117,"published":140,"mentions":179},"recommendations\u002Fandrey-stikheev","Andrey Stikheev","2026-09-08",[180,183],{"project":181,"quote":182},"product-image-editor","Among his most notable projects was a sophisticated browser-based image editor built with TypeScript and Fabric.js, now used by thousands of merchants.",{"project":184,"quote":185},"abandoned-carts","He also developed the frontend for a paid abandoned-cart product and contributed to the production migration from Vue 2 to Vue 3.",{"stem":187,"name":188,"date":189,"featured":134,"published":140,"mentions":190},"recommendations\u002Fdaniil-churakov","Daniil Churakov","2026-08-27",[],{"stem":192,"name":193,"date":194,"featured":124,"published":140,"mentions":195},"recommendations\u002Fdmitry-sadovsky","Dmitry Sadovsky","2026-08-22",[196,198,200,203],{"project":154,"quote":197},"For years he was the driving force behind our visual storefront editor — a large, complex application where merchants build their online stores.",{"project":181,"quote":199},"It became the tool merchants use to design product images right inside the admin panel — the kind of component companies usually buy rather than build.",{"project":201,"quote":202},"image-editor","What impressed me most was the infographic editor he built essentially from scratch: a full canvas-based graphic editor with artboards, shapes, text styling, templates, and undo\u002Fredo history, powered by an editor core he developed himself.",{"project":184,"quote":204},"Our abandoned carts functionality — with multi-channel customer messaging, communication history, and analytics — was largely his work, from UI down to the details of how requests are cancelled and states stay in sync.",{"stem":206,"name":207,"date":208,"featured":209,"published":140,"mentions":210},"recommendations\u002Fegor-fedkin","Egor Fedkin","2026-08-31",1,[211,213],{"project":181,"quote":212},"Today, the tool is actively used by around 3,000 users.",{"project":184,"quote":214},"It has already generated approximately twice the revenue needed to cover its development costs.",{"stem":216,"name":217,"date":218,"featured":134,"published":140,"mentions":219},"recommendations\u002Femmanuel-stephen","Emmanuel Stephen","2026-10-11",[],{"stem":221,"name":222,"date":223,"featured":134,"published":140,"mentions":224},"recommendations\u002Fevgeny-lonshakov","Евгений Лоншаков","2026-09-21",[],{"stem":226,"name":227,"date":228,"featured":134,"published":140,"mentions":229},"recommendations\u002Froman-gorbachev","Роман Горбачев","2026-09-17",[],{"stem":231,"name":232,"date":233,"featured":134,"published":140,"mentions":234},"recommendations\u002Fvladimir-bedarev","Bedarev Vladimir","2026-09-16",[],1793195987484]