Сервер
Определяет структуру и поведение UI
Сервер хранит компоненты UI
Кнопки, списки, баннеры и другие элементы определяются
на бэкенде
Мгновенные обновления
Изменения вступают в силу без обновления приложения
Единый код для всех платформ
iOS, Android и Web используют один и тот же APIПерсонализация для каждого пользователя
Разные сегменты пользователей получают разный интерфейс
Как это работает?
JSON / API
Передает инструкции клиенту
Клиент
Отрисовывает интерфейс на основе полученных инструкций
Проблемы, которые решает matreshka
Время вывода новых функций на рынок
традиционный
подход
matreshka
*согласно собственной статистике, накопленной на реализованных проектах
Как используют BDUI крупные компании
Распространение технологии
В 2024 году 34% новых мобильных стартапов выбирают BDUI.
Востребовано на всех континентах.
Ключевые отрасли
Адаптивные рекомендации и единый опыт на всех устройствах.
Динамические обновления и мгновенные изменения интерфейса.
Пример кода на Matreshka
new Card({ width: 250, outline: CardOutlineStyle.None, content: [ new Column({ align: { cross: ColumnCrossAxisAlign.SpaceBetween, }, height: 1, content: [ new Column({ content: [ new Image({ key: `${key}.image` }), new Heading({ level: 3, key: `${key}.name` }), new Text({ key: `${key}.description` }), ] }), new Column({ content: [ new Currency({ key: `${key}.price`, currency: "RUB" }), new Button({ label: new Text({ value: "Купить" }), style: ButtonStyle.Tint, }) ], }), ] }) ] })
new Heading({ level: 2, value: "Похожие товары" }), new Row({ scrollable: true, content: [ new ForEach({ key: "similarProducts", context: this.context, track: (data) => data.id, generator: ({ key }) => new Card({ width: 250, outline: CardOutlineStyle.None, content: [ new Column({ align: { cross: ColumnCrossAxisAlign.SpaceBetween, }, height: 1, content: [ new Column({ content: [ new Image({ key: `${key}.image` }), new Heading({ level: 3, key: `${key}.name` }), new Text({ key: `${key}.description` }), ] }), new Column({ content: [ new Currency({ key: `${key}.price`, currency: "RUB" }), new Button({ label: new Text({ value: "Купить" }), style: ButtonStyle.Tint, }) ], }), ] }) ] }) }), ] }),
new Heading({ level: 2, value: "Похожие товары" }), new Row({ scrollable: true, content: [ new ForEach({ key: "similarProducts", context: this.context, track: (data) => data.id, generator: ({ key }) => // Карточка товара }), ] }),
new Card({ outline: CardOutlineStyle.None, content: [ new Row({ content: [ // Изображение товара new Column({ width: { desktop: 0.4, tablet: 1, mobile: 1, }, content: [ new Image({ key: "product.image" }) ] }), // Информация о товаре new Column({ width: { desktop: 0.6, tablet: 1, mobile: 1, }, padding: { start: true, }, content: [ new Heading({ level: 1, key: "product.name" }), new Text({ key: "product.description" }), new Row({ content: [ new Currency({ key: "product.price", currency: "RUB" }) ], padding: { top: true, bottom: true, } }), new Button({ label: new Text({ value: "Добавить в корзину" }), style: ButtonStyle.Filled, onClick: () => { // some logic } }), new Button({ label: new Text({ value: "Купить в 1 клик" }), style: ButtonStyle.Tint, onClick: () => { // some logic } }), new Button({ label: new Text({ value: "Оформить рассрочку" }), style: ButtonStyle.Tint, onClick: () => { // some logic } }) ] }) ] }), ] })
// product = { id: "1", name: { ru: "Смартфон iPhone 15 Pro", en: "iPhone 15 Pro Smartphone" }, price: 99999, image: "https://images.biggeek.ru/1/870/4506/28465-146iphone-16-pro-finish-select-202409-6-3inch-blacktitanium@2x.jpg", description: { ru: "Новейший смартфон с мощным процессором A17 Pro, камерой 48 Мп и титановым корпусом.", en: "Latest smartphone with powerful A17 Pro processor, 48MP camera and titanium body." } }; content: [ new Image({ key: `product.image` }), new Heading({ level: 3, key: `product.name.@{language}` }), new Text({ key: `product.description.@{language}` }), ]
// На этапе добавления страниц в систему можно использовать условия для отображения страниц // Например, для бета-тестеров показываем новую версию, тут может быть любая логика // В данном случае, для всех пользователей, у которых в localStorage есть ключ beta-enabled со значением 1, показываем новую версию // Для всех остальных пользователей показываем старую версию matreshkaInstance.router.addPage( "/components/product-card", NewProductCardPage, async (client) => client.getStorageValue('beta-enabled') == '1'); matreshkaInstance.router.addPage( "/components/product-card", ProductCardPage );