
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
>
  <channel>
    <atom:link href="https://devmoek.ru/rss.xml" rel="self" type="application/rss+xml" />
    <title>moek</title>
    <link>https://devmoek.ru</link>
    <description>Блог фулл-стек разработчика moek о веб-разработке, фрилансе, Shopify и современных технологиях. Полезные статьи и советы для разработчиков, фрилансеров и тех, кто интересуется созданием сайтов и eCommerce решений.</description>
    <image>
      <url>https://devmoek.ru/favicons/favicon-32x32.png</url>
      <title>moek</title>
      <link>https://devmoek.ru</link>
      <width>32</width>
      <height>32</height>
    </image>
    
        <item>
          <guid>https://devmoek.ru/built-shopify-checkout-extension-app</guid>
          <title>Разработал приложение-расширение для Shopify магазина</title>
          <description>Shopify Plus открывает мир возможностей с помощью функции расширения чекаута. В этом посте я расскажу о своём опыте создание двух приложений-расширений для страницы оформления заказа...</description>
          <link>https://devmoek.ru/built-shopify-checkout-extension-app</link>
          <pubDate>Sun, 23 Mar 2025 21:55:27 +0000</pubDate>
          <category>shopify</category><category>shopify разработка</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/built-shopify-checkout-extension-app">
                  читать на сайте
                </a>
              </strong>
            </div>

            <p data-svelte-h="svelte-1j0ebba"><strong>Shopify Plus</strong> открывает мир возможностей с помощью функции расширения чекаута. В этом посте я расскажу о своём опыте создание двух приложений-расширений для страницы оформления заказа: баннер обратного отсчета и калькулятор записей. А также о том, как именно они улучшили страницу Checkout в Shopify магазине.</p> <h2 id="введение-в-приложения-расширения-extension-apps" data-svelte-h="svelte-1est987"><a class="heading-link" title="Permalink" aria-hidden="true" href="#введение-в-приложения-расширения-extension-apps"><span>#</span></a>Введение в приложения-расширения (Extension Apps)</h2> <p data-svelte-h="svelte-17skg2o">Расширения Checkout UI позволяют разработчикам приложений создавать пользовательские функции, которые продавцы могут устанавливать в определенных точках на странице оформления заказа, включая информацию о продукте, доставку, оплату, сводку заказа и Shop Pay.</p> <div class="callout-block info svelte-sxx0n0"><div class="icon-wrapper svelte-sxx0n0"><svg width="100%" height="100%" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 11.5V16.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 7.51L12.01 7.49889" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></div> Расширения пользовательского интерфейса чекаута для шага «Информация», «Доставка» и «Оплата» доступны только магазинам на тарифе Shopify Plus.</div> <h2 id="запрос-на-разработку" data-svelte-h="svelte-se8z4a"><a class="heading-link" title="Permalink" aria-hidden="true" href="#запрос-на-разработку"><span>#</span></a>Запрос на разработку</h2> <p data-svelte-h="svelte-1wsdpbm">Мне пришёл запрос на расширение чекаута в Shopify. У Shopify есть <code>Checkout UI Extensions</code>. Расширения позволяют кастомизировать страницу чекаут как вы хотите (почти).</p> <p data-svelte-h="svelte-1lin8dy">Есть определённые области (extension points) куда можно добавить кастомный блок.</p> <p data-svelte-h="svelte-1mq0myg"><img src="https://shopify.dev/assets/templated-apis-screenshots/checkout-ui-extensions/2025-01/extension-targets.png" alt="области для кастомного блока в шопифай чекауте"></p> <p data-svelte-h="svelte-1cle0w3">Блоки бывают разные: <strong>статический</strong> или <strong>динамический</strong>. <strong>Статический блок</strong> это обычно текстовый баннер. Например, предупреждение пользователя о загруженности магазина. <strong>Динамический блок</strong> это когда нужна какая-то логика, например, показывать сообщение если в чекауте лежит n количество товаров, или применять скидку на определённые товары.</p> <a href="https://shopify.pxf.io/jWEzd0" target="_blank" rel="noopener noreferrer" class="button style--solid size--medium color--primary  svelte-hsaxku" data-sveltekit-preload-data> Shopify магазин за $1/мес.</a> <h2 id="что-было-разработано" data-svelte-h="svelte-1589bzy"><a class="heading-link" title="Permalink" aria-hidden="true" href="#что-было-разработано"><span>#</span></a>Что было разработано</h2> <p data-svelte-h="svelte-89e7rb"><img src="/images/posts/shopify-checkout-extension-app.png" alt="разработка расширения для Shopify чекаута"></p> <h4 id="баннер-обратного-отсчёта" data-svelte-h="svelte-n9egu9"><a class="heading-link" title="Permalink" aria-hidden="true" href="#баннер-обратного-отсчёта"><span>#</span></a>Баннер обратного отсчёта</h4> <p data-svelte-h="svelte-w36ofi">Показывает таймер. Когда таймер заканчивается, появляется вопрос «Нужно ли вам еще время» и ответы «Да» или «Нет».</p> <h4 id="калькулятор-билетов" data-svelte-h="svelte-1ixb4ju"><a class="heading-link" title="Permalink" aria-hidden="true" href="#калькулятор-билетов"><span>#</span></a>Калькулятор билетов</h4> <p data-svelte-h="svelte-dzn04m">Этот вариант более сложный, чем баннер обратного отсчёта. В нем есть логика. Некоторые продукты имеют множитель 5x, а некоторые 10x. И, конечно, бонусы тоже имеют свою логику. Сильно углубляться не буду.</p> <p data-svelte-h="svelte-179z4n3">Изначально была идея “прицепиться” к тэгу товаров или типу. И так я и сделал, использовал тип продукта для множителя, но после переписал логику и начал использовать метаполя (metafields). Метаполя более универсальный вариант. Теперь у каждого товара может быть свой множитель.</p> <h2 id="как-начать-разработку-checkout-extension-app" data-svelte-h="svelte-mmudsp"><a class="heading-link" title="Permalink" aria-hidden="true" href="#как-начать-разработку-checkout-extension-app"><span>#</span></a>Как начать разработку Checkout Extension App?</h2> <p data-svelte-h="svelte-16xoh2v">Чтобы начать разработку чекаут расширения, вставьте эти команды в терминал:</p> <pre class="language-bash"><!-- HTML_TAG_START --><code class="language-bash"><span class="token function">npm</span> init @shopify/app@latest
<span class="token builtin class-name">cd</span> your-app
<span class="token function">npm</span> run shopify app generate extension</code><!-- HTML_TAG_END --></pre> <h3 id="необходимые-условия" data-svelte-h="svelte-bdoevn"><a class="heading-link" title="Permalink" aria-hidden="true" href="#необходимые-условия"><span>#</span></a>Необходимые условия:</h3> <ul data-svelte-h="svelte-1kdqcpz"><li>Тариф Shopify Plus: Пользовательская проверка доступна только для магазинов Plus.</li> <li>Партнерский Shopify аккаунт: Требуется для создания и развертывания приложения.</li> <li>Среда разработки: Используйте Shopify CLI, Node.js и редактор кода для создания приложения.</li></ul> <p data-svelte-h="svelte-24tpk4"><a href="https://shopify.dev/docs/api/checkout-ui-extensions?ref=blog.devmoek.com" title="Открыть документацию Shopify" rel="nofollow">Официальная документация</a></p> <h2 id="заключение" data-svelte-h="svelte-lr9prh"><a class="heading-link" title="Permalink" aria-hidden="true" href="#заключение"><span>#</span></a>Заключение</h2> <p data-svelte-h="svelte-1kh81fk">Расширяемость Shopify Checkout позволяет магазинам на тарифе Shopify Plus легко создавать индивидуальный опыт оформления заказа, который соответствует их уникальным потребностям.</p> <p data-svelte-h="svelte-1jr6007">В своём недавнем проекте я в очередной раз убедился, что Shopify очень удобный в разработке. Создав такие расширения для чекаута, как баннер с обратным отсчётом, чтобы увеличить конверсию магазина, и калькулятор билетов с интеллектуальной логикой для более понятного вычисления билетов на странице оформления заказа.</p> <a href="https://t.me/themoek" target="_blank" rel="noopener noreferrer" class="button style--solid size--medium color--primary  svelte-hsaxku" data-sveltekit-preload-data> Заказать Shopify разработку</a>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/shopify-checkout-extension-app.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/shopify-checkout-extension-app.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/freelance-bez-platform</guid>
          <title>Фриланс без площадок — Полное руководство</title>
          <description>Вы ищете возможности работы фрилансером? Существует множество веб-сайтов, которые предоставляют фрилансерам площадки для общения с клиентами и поиска работы.</description>
          <link>https://devmoek.ru/freelance-bez-platform</link>
          <pubDate>Thu, 26 Dec 2024 21:55:15 +0000</pubDate>
          <category>фриланс</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/freelance-bez-platform">
                  читать на сайте
                </a>
              </strong>
            </div>

            <p data-svelte-h="svelte-rpsecr">Что вы думаете, когда слышите про фриланс? Переработки, отсутствие выходных и непостоянная занятость? А ещё площадки и где именно искать клиентов?</p> <p data-svelte-h="svelte-7jkku7">Фриланс — это не просто работа вне офиса, это стиль жизни. Многие начинающие фрилансеры выбирают специализированные платформы (Upwork, Fiverr, FL.ru и т.д.) для поиска клиентов. Но что, если отказаться от этих площадок?</p> <p data-svelte-h="svelte-1bwusur">В этой статье я подробно разберу, как работает фриланс без посредников, его плюсы и минусы, а также стратегии успеха.</p> <h2 id="что-такое-фриланс-без-площадок" data-svelte-h="svelte-1lebq5f"><a class="heading-link" title="Permalink" aria-hidden="true" href="#что-такое-фриланс-без-площадок"><span>#</span></a>Что такое фриланс без площадок?</h2> <p data-svelte-h="svelte-1anv8r8">Фриланс без площадок — это модель работы, где вы находите клиентов напрямую, минуя посредников. Весь процесс, от поиска заказов до выставления счетов, фрилансер организует самостоятельно.</p> <p data-svelte-h="svelte-14h9khy">Это может включать:</p> <ul data-svelte-h="svelte-5idwdr"><li>Работа по рекомендациям;</li> <li>Активное использование соцсетей и профессиональных сообществ;</li> <li>Создание личного бренда;</li> <li>Ведение своего сайта или блога;</li> <li>Прямую рассылку коммерческих предложений (outreach).</li></ul> <h2 id="плюсы-работы-без-площадок" data-svelte-h="svelte-1qozhlb"><a class="heading-link" title="Permalink" aria-hidden="true" href="#плюсы-работы-без-площадок"><span>#</span></a>Плюсы работы без площадок</h2> <h3 id="отсутствие-комиссии" data-svelte-h="svelte-1imoicj"><a class="heading-link" title="Permalink" aria-hidden="true" href="#отсутствие-комиссии"><span>#</span></a>Отсутствие комиссии</h3> <p data-svelte-h="svelte-1yff8z5">Фриланс-платформы берут до 20% комиссии с каждого заказа. Без них все заработанное остается у вас.</p> <h3 id="свобода-ценообразования" data-svelte-h="svelte-nykil"><a class="heading-link" title="Permalink" aria-hidden="true" href="#свобода-ценообразования"><span>#</span></a>Свобода ценообразования</h3> <p data-svelte-h="svelte-1rrp2ch">Вы самостоятельно определяете стоимость услуг. Нет необходимости конкурировать с демпингующими новичками.</p> <h3 id="развитие-личного-бренда" data-svelte-h="svelte-18kljh2"><a class="heading-link" title="Permalink" aria-hidden="true" href="#развитие-личного-бренда"><span>#</span></a>Развитие личного бренда</h3> <p data-svelte-h="svelte-11s7pe5">Работая напрямую, вы строите репутацию в своей нише, а не «прокачиваете» профиль на платформе.</p> <h3 id="контроль-за-процессами" data-svelte-h="svelte-1trzz7k"><a class="heading-link" title="Permalink" aria-hidden="true" href="#контроль-за-процессами"><span>#</span></a>Контроль за процессами</h3> <p data-svelte-h="svelte-1cbogr5">Вы выбираете, с кем работать, на каких условиях, и как управлять проектами.</p> <h3 id="лояльные-клиенты" data-svelte-h="svelte-5exuwt"><a class="heading-link" title="Permalink" aria-hidden="true" href="#лояльные-клиенты"><span>#</span></a>Лояльные клиенты</h3> <p data-svelte-h="svelte-1s9hxzd">Прямые клиенты чаще становятся постоянными, так как они работают с вами лично, а не через обезличенную систему.</p> <h2 id="минусы-фриланса-без-площадок" data-svelte-h="svelte-gk4568"><a class="heading-link" title="Permalink" aria-hidden="true" href="#минусы-фриланса-без-площадок"><span>#</span></a>Минусы фриланса без площадок</h2> <h3 id="сложность-поиска-клиентов" data-svelte-h="svelte-1a8f6go"><a class="heading-link" title="Permalink" aria-hidden="true" href="#сложность-поиска-клиентов"><span>#</span></a>Сложность поиска клиентов</h3> <p data-svelte-h="svelte-1klgb2m">Особенно для новичков, которые не имеют портфолио и рекомендаций.</p> <h3 id="административная-нагрузка" data-svelte-h="svelte-d9lumx"><a class="heading-link" title="Permalink" aria-hidden="true" href="#административная-нагрузка"><span>#</span></a>Административная нагрузка</h3> <p data-svelte-h="svelte-1w7dxqt">Фрилансеру нужно самостоятельно заниматься договорами, отчетностью и оплатой налогов.</p> <h3 id="риски-мошенничества" data-svelte-h="svelte-4k8i5o"><a class="heading-link" title="Permalink" aria-hidden="true" href="#риски-мошенничества"><span>#</span></a>Риски мошенничества</h3> <p data-svelte-h="svelte-1d7ytcc">Без посредников сложнее защитить себя от недобросовестных клиентов.</p> <h3 id="маркетинг-на-ваших-плечах" data-svelte-h="svelte-1kl6z71"><a class="heading-link" title="Permalink" aria-hidden="true" href="#маркетинг-на-ваших-плечах"><span>#</span></a>Маркетинг на ваших плечах</h3> <p data-svelte-h="svelte-4ff405">Придется уделять время продвижению личныого сайта, соцсетей, рассылок, и PR.</p> <h2 id="почему-фриланс-без-площадок-работает" data-svelte-h="svelte-w87sy7"><a class="heading-link" title="Permalink" aria-hidden="true" href="#почему-фриланс-без-площадок-работает"><span>#</span></a>Почему фриланс без площадок работает?</h2> <ul data-svelte-h="svelte-xos38b"><li><p><strong>Принцип «Сарафанного радио»</strong></p> <p>Люди чаще доверяют рекомендациям знакомых. Построение репутации через качество работы приводит к росту базы клиентов.</p></li> <li><p><strong>Эффект доверия</strong></p> <p>Прямое взаимодействие позволяет выстраивать личные отношения с клиентами, что повышает лояльность.</p></li> <li><p><strong>Автономность и независимость</strong></p> <p>Фрилансер, работающий без площадок, быстрее адаптируется к рынку и становится более гибким в изменяющихся условиях.</p></li></ul> <h2 id="факты-и-цифры" data-svelte-h="svelte-yudhst"><a class="heading-link" title="Permalink" aria-hidden="true" href="#факты-и-цифры"><span>#</span></a>Факты и цифры</h2> <h3 id="рост-личного-бренда-увеличивает-доходы" data-svelte-h="svelte-17i14ry"><a class="heading-link" title="Permalink" aria-hidden="true" href="#рост-личного-бренда-увеличивает-доходы"><span>#</span></a>Рост личного бренда увеличивает доходы</h3> <p data-svelte-h="svelte-1d5tv7i">Фрилансеры с активными соцсетями зарабатывают на 40% больше, чем их коллеги, использующие только платформы.</p> <h3 id="80-клиентов-приходят-по-рекомендациям" data-svelte-h="svelte-1lnxkhp"><a class="heading-link" title="Permalink" aria-hidden="true" href="#80-клиентов-приходят-по-рекомендациям"><span>#</span></a>80% клиентов приходят по рекомендациям</h3> <p data-svelte-h="svelte-1307fbb">Исследования показывают, что клиенты предпочитают работать с фрилансерами, которых им порекомендовали знакомые.</p> <h3 id="собственный-сайт-увеличивает-шансы-на-успех" data-svelte-h="svelte-1xi3lfn"><a class="heading-link" title="Permalink" aria-hidden="true" href="#собственный-сайт-увеличивает-шансы-на-успех"><span>#</span></a>Собственный сайт увеличивает шансы на успех</h3> <p data-svelte-h="svelte-ant65r">Фрилансеры с личным сайтом получают до 65% больше заказов, так как выглядят более профессионально.</p> <h2 id="стратегии-для-успешного-фриланса-без-площадок" data-svelte-h="svelte-1axh7fl"><a class="heading-link" title="Permalink" aria-hidden="true" href="#стратегии-для-успешного-фриланса-без-площадок"><span>#</span></a>Стратегии для успешного фриланса без площадок</h2> <ol data-svelte-h="svelte-ie91s0"><li><p><strong>Создание сильного портфолио</strong></p> <p>Разместите ваши работы на Behance, Dribbble, Dprofile или просто на личном сайте. Покажите не только результат, но и процесс работы.</p></li> <li><p><strong>Активность в соцсетях</strong></p> <p>Используйте LinkedIn, Instagram, TikTok и тематические Telegram-каналы. Делитесь экспертизой и показывайте кейсы.</p></li> <li><p><strong>Разработка личного бренда</strong></p> <ul><li>Пишите статьи;</li> <li>Участвуйте в конференциях;</li> <li>Делайте экспертные посты.</li></ul></li> <li><p>Нетворкинг</p> <p>Знакомьтесь с людьми из вашей ниши. Это могут быть как клиенты, так и другие фрилансеры, которые порекомендуют вас.</p></li> <li><p><strong>Рассылки и cold outreach</strong></p> <p>Научитесь грамотно писать коммерческие предложения. Укажите, как вы можете решить проблему клиента, и подкрепите это примерами.</p></li></ol> <h2 id="практические-советы" data-svelte-h="svelte-1gaq5bl"><a class="heading-link" title="Permalink" aria-hidden="true" href="#практические-советы"><span>#</span></a>Практические советы</h2> <h3 id="1-запустите-сайт-визитку-с-seo" data-svelte-h="svelte-1c9zv18"><a class="heading-link" title="Permalink" aria-hidden="true" href="#1-запустите-сайт-визитку-с-seo"><span>#</span></a>1. Запустите сайт-визитку с SEO</h3> <p data-svelte-h="svelte-1fvjbh0">Оптимизируйте сайт под ключевые запросы вашей ниши: «дизайнер логотипов», «разработчик на Shopify», «motion дизайнер», «SMM менеджер», и тд.</p> <h3 id="2-инвестируйте-в-личный-бренд" data-svelte-h="svelte-5n8x23"><a class="heading-link" title="Permalink" aria-hidden="true" href="#2-инвестируйте-в-личный-бренд"><span>#</span></a>2. Инвестируйте в личный бренд</h3> <p data-svelte-h="svelte-1fjbqyb">Курсы, вебинары, качественный контент помогут укрепить репутацию.</p> <h3 id="3-работайте-по-договору" data-svelte-h="svelte-1879f3w"><a class="heading-link" title="Permalink" aria-hidden="true" href="#3-работайте-по-договору"><span>#</span></a>3. Работайте по договору</h3> <p data-svelte-h="svelte-1xxdsaf">Составьте шаблон договора для работы с клиентами. Это обезопасит клиента от обмана, а вас от большого количества правок.</p> <h3 id="4-автоматизируйте-процессы" data-svelte-h="svelte-sld99k"><a class="heading-link" title="Permalink" aria-hidden="true" href="#4-автоматизируйте-процессы"><span>#</span></a>4. Автоматизируйте процессы</h3> <p data-svelte-h="svelte-d8fd5c">Используйте CRM для управления клиентами и сервисы для выставления счетов. Когда у вас станет больше 10 клиентов, их нужно будет куда-то сохранить. Вы, конечно, можете выписать имя и почту клиента в блокнот, но CRM-система это проще и быстрее.</p> <h2 id="заключение" data-svelte-h="svelte-lr9prh"><a class="heading-link" title="Permalink" aria-hidden="true" href="#заключение"><span>#</span></a>Заключение</h2> <p data-svelte-h="svelte-ws11u8">Фриланс без площадок — это выбор для тех, кто готов взять ответственность за свою карьеру. Он дает свободу, контроль и возможность заработать больше. Однако, чтобы добиться успеха, необходимо инвестировать время и ресурсы в развитие личного бренда и маркетинг.</p> <h3 id="нужна-помощь" data-svelte-h="svelte-rbgue3"><a class="heading-link" title="Permalink" aria-hidden="true" href="#нужна-помощь"><span>#</span></a>Нужна помощь?</h3> <p data-svelte-h="svelte-1qzdue3">Консультация проходит в Zoom тет-а-тет. Если у вас есть какие-либо вопросы или сложности, я вам помогу.</p> <a href="https://cal.com/devmoek" target="_blank" rel="noopener noreferrer" class="button style--solid size--medium color--primary  svelte-hsaxku" data-sveltekit-preload-data> Заказать консультацию</a>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/freelance-bez-ploshadok.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/freelance-bez-ploshadok.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/shopify-themes-2.0-obzor</guid>
          <title>Обзор Shopify Тем 2.0</title>
          <description>Shopify 2.0 — это обновленная версия платформы для интернет-магазинов с улучшенной гибкостью тем, поддержкой блоков на всех страницах, глобальными настройками дизайна, JSON-шаблонами и новыми инструментами для разработчиков. Она обеспечивает лучшую производительность и SEO-оптимизацию, упрощая создание и управление онлайн-магазинами.</description>
          <link>https://devmoek.ru/shopify-themes-2.0-obzor</link>
          <pubDate>Fri, 07 Jun 2024 21:55:15 +0000</pubDate>
          <category>shopify</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/shopify-themes-2.0-obzor">
                  читать на сайте
                </a>
              </strong>
            </div>

            <div class="callout-block info svelte-sxx0n0"><div class="icon-wrapper svelte-sxx0n0"><svg width="100%" height="100%" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 11.5V16.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 7.51L12.01 7.49889" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></div> Shopify Онлайн Магазины 2.0 были аннонсированы и запущены 29 июня 2021 года.</div> <h2 id="основные-преимущества" data-svelte-h="svelte-1uz4n9y"><a class="heading-link" title="Permalink" aria-hidden="true" href="#основные-преимущества"><span>#</span></a>Основные преимущества</h2> <p data-svelte-h="svelte-1wsxjri">1️⃣ <strong>Улучшенная настройка:</strong> Больше возможностей для индивидуализации вашего магазина без необходимости вмешательства в код.</p> <p data-svelte-h="svelte-1z0e5x1">2️⃣ <strong>Новые инструменты для разработчиков:</strong> От интеграции с GitHub до улучшенного CLI – разработка стала проще и эффективнее.</p> <p data-svelte-h="svelte-g8266q">3️⃣ <strong>Адаптивные под мобильные устройства:</strong> Улучшенный дизайн и функциональность для мобильных пользователей.</p> <p data-svelte-h="svelte-1elu0y9">4️⃣ <strong>Новый подход к темам:</strong> Переход от <code>.liquid</code> шаблонов к <code>JSON</code>, что позволяет создавать динамические секции.</p> <p data-svelte-h="svelte-mvy81t">5️⃣ <strong>Улучшенная скорость загрузки:</strong> Сайты на темах 2.0 загружаются быстрее, чем 1.0.</p> <div class="callout-block warning svelte-sxx0n0"><div class="icon-wrapper svelte-sxx0n0"><svg width="100%" height="100%" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 7L12 13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 17.01L12.01 16.9989" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></div> Обновитесь на Shopify 2.0, чтобы воспользоваться всеми этими преимуществами и вывести ваш магазин на новый уровень.</div> <a href="https://t.me/themoek" target="_blank" rel="noopener noreferrer" class="button style--solid size--medium color--primary  svelte-hsaxku" data-sveltekit-preload-data> Заказать обновление магазина</a> <p data-svelte-h="svelte-1w7et5x">При клике на кнопку будет открыт Телеграм.</p>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/shopify-2.0.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/shopify-2.0.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/medusajs-shopify-alternative</guid>
          <title>Medusa.js - бесплатная альтернатива Shopify?</title>
          <description>Medusa.js — бесплатная альтернатива Shopify, идеально подходящая для создания интернет-магазинов. Узнайте, как использовать эту платформу с открытым исходным кодом для разработки масштабируемых eCommerce решений, экономии бюджета и получения гибкости в управлении продажами.</description>
          <link>https://devmoek.ru/medusajs-shopify-alternative</link>
          <pubDate>Thu, 04 Apr 2024 21:55:15 +0000</pubDate>
          <category>shopify</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/medusajs-shopify-alternative">
                  читать на сайте
                </a>
              </strong>
            </div>

            <p data-svelte-h="svelte-13d627m"><em>Обложка поста: <a href="https://www.google.com/url?sa=i&url=https%3A%2F%2Fgithub.com%2Fmedusajs%2Fmedusa&psig=AOvVaw20dO25SYcErU5BPRTjz31g&ust=1712326055372000&source=images&cd=vfe&opi=89978449&ved=0CBQQjhxqFwoTCIiX5drdqIUDFQAAAAAdAAAAABAE" rel="nofollow">Medusa.js</a>.</em></p> <p data-svelte-h="svelte-7p5khv">Если вы знакомы c электронной коммерцией, то, возможно, слышали про Медузу, и я сейчас не про СМИ (26 января 2023 года Генеральная прокуратура России признала «Медузу» «нежелательной организацией»).</p> <h2 id="что-такое-medusajs" data-svelte-h="svelte-zc5p4s"><a class="heading-link" title="Permalink" aria-hidden="true" href="#что-такое-medusajs"><span>#</span></a>Что такое Medusa.js?</h2> <blockquote data-svelte-h="svelte-bel4ca"><p>Медуза - Один из самых популярных проектов электронной коммерции на GitHub. Medusa предоставляет серверную инфраструктуру электронной коммерции с открытым исходным кодом на NodeJS.</p></blockquote> <p data-svelte-h="svelte-115pbum">Если простыми словами — Медуза это бэкенд для вашего интернет-магазина.</p> <h2 id="преимущества-medusajs" data-svelte-h="svelte-6gh32b"><a class="heading-link" title="Permalink" aria-hidden="true" href="#преимущества-medusajs"><span>#</span></a>Преимущества Medusa.js</h2> <h3 id="1-полный-контроль" data-svelte-h="svelte-xrjvvp"><a class="heading-link" title="Permalink" aria-hidden="true" href="#1-полный-контроль"><span>#</span></a>1. Полный контроль.</h3> <p data-svelte-h="svelte-1ffqj84">Используя Медузу, вы имеете полный контроль над вашим e-commerce магазином. Единственное, вам понадобится <strong>сервер</strong>.</p> <p data-svelte-h="svelte-ya929q">Для того чтобы хранить базу данных, вам нужно хранилище (сервер). Существует множество сервисов, которые предоставляют выделенный сервер, вот что рекомендует Медуза: <a href="https://www.heroku.com/" rel="nofollow">Heroku</a>, <a href="https://try.digitalocean.com/" rel="nofollow">DigitalOcean</a>, <a href="https://railway.app/" rel="nofollow">Railway</a>, <a href="https://www.microtica.com/" rel="nofollow">Microtica</a>, и свой вариант (вдруг у вас уже есть сервер на другом сервисе).</p> <h3 id="2-гибкость-в-разработке-фронтенда" data-svelte-h="svelte-1hjgjly"><a class="heading-link" title="Permalink" aria-hidden="true" href="#2-гибкость-в-разработке-фронтенда"><span>#</span></a>2. Гибкость в разработке фронтенда</h3> <p data-svelte-h="svelte-meov4q">Medusa.js не накладывает ограничений на выбор технологий для создания витрины магазина. Вы можете использовать любой современный JavaScript-фреймворк, например, <code>React</code>, <code>Vue.js</code>, <code>Svelte</code>, или <code>Remix</code>. Это позволяет создать уникальный пользовательский интерфейс, который полностью соответствует вашим требованиям.</p> <h3 id="3-интеграции" data-svelte-h="svelte-1lmchfr"><a class="heading-link" title="Permalink" aria-hidden="true" href="#3-интеграции"><span>#</span></a>3. Интеграции</h3> <p data-svelte-h="svelte-1pmhwa8">Medusa.js поддерживает интеграции с популярными сервисами, такими как Stripe, PayPal, и другими платёжными системами. Это облегчает создание сложных eCommerce решений, включая мультивалютность, управление запасами и аналитические инструменты.</p> <h2 id="ограничения-medusajs" data-svelte-h="svelte-qxhy83"><a class="heading-link" title="Permalink" aria-hidden="true" href="#ограничения-medusajs"><span>#</span></a>Ограничения Medusa.js</h2> <p data-svelte-h="svelte-g0ayfu">Несмотря на преимущества, Medusa.js подходит не всем. Вот несколько ключевых ограничений:</p> <h3 id="1-требования-к-техническим-знаниям" data-svelte-h="svelte-1lrxf1y"><a class="heading-link" title="Permalink" aria-hidden="true" href="#1-требования-к-техническим-знаниям"><span>#</span></a>1. Требования к техническим знаниям</h3> <p data-svelte-h="svelte-1gflmko">Если вы не разработчик или у вас нет команды разработчиков, работа с Medusa.js может быть сложной. Платформа требует глубокого понимания серверных технологий, настройки баз данных и разработки пользовательских интерфейсов.</p> <h3 id="2-отсутствие-встроенного-редактора-тем" data-svelte-h="svelte-1fg2eye"><a class="heading-link" title="Permalink" aria-hidden="true" href="#2-отсутствие-встроенного-редактора-тем"><span>#</span></a>2. Отсутствие встроенного редактора тем</h3> <p data-svelte-h="svelte-8tg9jm">Shopify предлагает удобный редактор тем, который позволяет вносить изменения в дизайн магазина без написания кода. В Medusa.js такого инструмента нет, поэтому все изменения необходимо вносить вручную через код.</p> <h3 id="3-поддержка" data-svelte-h="svelte-99yhrk"><a class="heading-link" title="Permalink" aria-hidden="true" href="#3-поддержка"><span>#</span></a>3. Поддержка</h3> <p data-svelte-h="svelte-kzmnlm">Если вы выбираете Medusa.js, будьте готовы к тому, что все вопросы поддержки магазина ложатся на ваши плечи или плечи вашей команды разработчиков. В отличие от Shopify, где есть централизованная служба поддержки, в случае с Medusa.js придётся рассчитывать на сообщество и документацию.</p> <h2 id="кому-подходит-medusajs" data-svelte-h="svelte-10p8uix"><a class="heading-link" title="Permalink" aria-hidden="true" href="#кому-подходит-medusajs"><span>#</span></a>Кому подходит Medusa.js?</h2> <p data-svelte-h="svelte-1w6l1jm">Medusa.js — это идеальный выбор для компаний, которым нужны кастомные eCommerce решения. Например, если ваш магазин требует уникальных функций, сложных интеграций или нестандартного дизайна, Medusa.js предоставит вам необходимые инструменты. Однако для небольших магазинов с ограниченным бюджетом и ресурсами лучше выбрать готовые платформы, такие как Shopify.</p> <p data-svelte-h="svelte-1qaj5t0"><a href="/tags/shopify">Читать про Shopify</a></p> <h2 id="заключение" data-svelte-h="svelte-lr9prh"><a class="heading-link" title="Permalink" aria-hidden="true" href="#заключение"><span>#</span></a>Заключение</h2> <p data-svelte-h="svelte-1e07drs">Медуза — интересная альтернатива Shopify, особенно для технически подкованных пользователей. Платформа предлагает полный контроль над проектом и позволяет создать уникальный опыт электронной коммерции.</p> <p data-svelte-h="svelte-105l1r7">Однако за эту гибкость приходится платить:</p> <ul data-svelte-h="svelte-1fhtag5"><li>сложностью настройки;</li> <li>необходимостью знаний в области программирования и отсутствием встроенных инструментов для управления витриной.</li></ul> <p data-svelte-h="svelte-7wn4fb">Если вы готовы к этим вызовам, Medusa.js может стать отличным выбором для реализации вашего интернет-магазина мечты.</p> <p data-svelte-h="svelte-1wcewvm">Не можете определиться с платформой для вашего магазина? Я вам помогу.</p> <a href="https://cal.com/devmoek" target="_blank" rel="noopener noreferrer" class="button style--solid size--medium color--primary  svelte-hsaxku" data-sveltekit-preload-data> Заказать консультацию</a>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/medusajs-besplatnaya-shopify-alternativa.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/medusajs-besplatnaya-shopify-alternativa.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/devin-ai</guid>
          <title>Devin AI. ИИ который заберёт вашу работу?</title>
          <description>Недавно появился новый ИИ. В этот раз выпустили не просто ИИ, а ИИ-программист. То есть это бот с упором на программирование. В чём подвох?</description>
          <link>https://devmoek.ru/devin-ai</link>
          <pubDate>Sat, 16 Mar 2024 21:55:15 +0000</pubDate>
          <category>AI</category><category>ИИ</category><category>технологии</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/devin-ai">
                  читать на сайте
                </a>
              </strong>
            </div>

            <p data-svelte-h="svelte-19zrtgf">Недавно выпустили новый искусственный интеллект.</p> <blockquote class="twitter-tweet" data-media-max-width="100%" data-lang="ru" data-svelte-h="svelte-1v677h7"><p lang="en" dir="ltr">Today we&#39;re excited to introduce Devin, the first AI software engineer.<br><br>Devin is the new state-of-the-art on the SWE-Bench coding benchmark, has successfully passed practical engineering interviews from leading AI companies, and has even completed real jobs on Upwork.<br><br>Devin is… <a href="https://t.co/ladBicxEat">pic.twitter.com/ladBicxEat</a></p>— Cognition (@cognition_labs) <a href="https://twitter.com/cognition_labs/status/1767548763134964000?ref_src=twsrc%5Etfw">12 марта 2024 г.</a></blockquote> <p data-svelte-h="svelte-1tnqxl1">Понимаю, тема уже надоела. Но в этот раз выпустили не просто ИИ, а ИИ-программист. То есть это бот с упором на программирование. В чём подвох?</p> <p data-svelte-h="svelte-bfwxk0">Давайте посмотрим на то, что предлагают разработчики этого чуда. Они говорят, что это убийца всех других ИИ и решает задачи в несколько раз лучше GPT-4. Кстати, GPT-4 уже год.</p> <h2 id="что-может-devin" data-svelte-h="svelte-pumaqi"><a class="heading-link" title="Permalink" aria-hidden="true" href="#что-может-devin"><span>#</span></a>Что может Devin?</h2> <ol data-svelte-h="svelte-we9h50"><li>Девин может научиться использовать незнакомые технологии;
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ru" data-theme="dark"><p lang="en" dir="ltr">1/4 Devin can learn how to use unfamiliar technologies. <a href="https://t.co/UXWxSp6Lv8">pic.twitter.com/UXWxSp6Lv8</a></p>— Cognition (@cognition_labs) <a href="https://twitter.com/cognition_labs/status/1767548764623921476?ref_src=twsrc%5Etfw">12 марта 2024 г.</a></blockquote></li> <li>Девин может вносить изменения в репозитории;
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ru" data-theme="dark"><p lang="en" dir="ltr">2/4 Devin can contribute to mature production repositories. <a href="https://t.co/0CsISZnKSA">pic.twitter.com/0CsISZnKSA</a></p>— Cognition (@cognition_labs) <a href="https://twitter.com/cognition_labs/status/1767548765924114881?ref_src=twsrc%5Etfw">12 марта 2024 г.</a></blockquote></li> <li>Девин может обучать и настраивать собственные ИИ модели;
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ru" data-theme="dark"><p lang="en" dir="ltr">3/4 Devin can train and fine tune its own AI models. <a href="https://t.co/WSGSO5evsL">pic.twitter.com/WSGSO5evsL</a></p>— Cognition (@cognition_labs) <a href="https://twitter.com/cognition_labs/status/1767548767337672895?ref_src=twsrc%5Etfw">12 марта 2024 г.</a></blockquote></li> <li>Девин может выполнять реальные заказы на фрилансе.
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ru" data-theme="dark"><p lang="en" dir="ltr">4/4 We even tried giving Devin real jobs on Upwork and it could do those too! <a href="https://t.co/7XUWQLeZm1">pic.twitter.com/7XUWQLeZm1</a></p>— Cognition (@cognition_labs) <a href="https://twitter.com/cognition_labs/status/1767548768734294113?ref_src=twsrc%5Etfw">12 марта 2024 г.</a></blockquote></li></ol> <h2 id="стоит-ли-вашего-внимания" data-svelte-h="svelte-67yrt"><a class="heading-link" title="Permalink" aria-hidden="true" href="#стоит-ли-вашего-внимания"><span>#</span></a>Стоит ли вашего внимания?</h2> <p data-svelte-h="svelte-yzcdn1">Не хочу показаться старым дедом, но как по мне это уже не удивляет. Я помню бум с Chat GPT и вот тогда было да, революционно. А сейчас как-будто все вот эти новые модели создаются лишь бы грести большое количество денег. Я могу ошибаться, посмотрим, что из этого получится.</p> <h2 id="будет-ли-видео" data-svelte-h="svelte-jpxekx"><a class="heading-link" title="Permalink" aria-hidden="true" href="#будет-ли-видео"><span>#</span></a>Будет ли видео?</h2> <p data-svelte-h="svelte-563cat">Я долго думал выпускать ли видео о GPT, когда он только появился. Но что-то пока думал, уже вся шумиха прошла. Теперь думаю с этим ИИ, стоит или не стоит. Особо ничего нового я не расскажу, но чтобы оставить на память можно снять, посмотрим.</p>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/devin_ai_obzor.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/devin_ai_obzor.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/react-19-obzor</guid>
          <title>Что нового в React 19?</title>
          <description>В React 19 было представлено несколько новых функций и улучшений, включая автоматическую группировку (batching), серверные компоненты, конкурентные функции и различные оптимизации для улучшения как разработки, так и пользовательского опыта.</description>
          <link>https://devmoek.ru/react-19-obzor</link>
          <pubDate>Fri, 23 Feb 2024 21:55:27 +0000</pubDate>
          <category>react</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/react-19-obzor">
                  читать на сайте
                </a>
              </strong>
            </div>

            <h2 id="почему-react" data-svelte-h="svelte-zvifgt"><a class="heading-link" title="Permalink" aria-hidden="true" href="#почему-react"><span>#</span></a>Почему React?</h2> <p data-svelte-h="svelte-1qidlc0">React, один из самых популярных инструментов для разработки пользовательских интерфейсов, достиг важной вехи с выпуском версии 19.</p> <h2 id="новвоведения-в-react-19" data-svelte-h="svelte-97p83f"><a class="heading-link" title="Permalink" aria-hidden="true" href="#новвоведения-в-react-19"><span>#</span></a>Новвоведения в React 19</h2> <p data-svelte-h="svelte-10fmvde">В React 19 было представлено несколько новых функций и улучшений, включая автоматическую группировку (batching), серверные компоненты, конкурентные функции и различные оптимизации для улучшения как разработки, так и пользовательского опыта.</p> <p data-svelte-h="svelte-kr708t">Вот краткое изложение ключевых обновлений:</p> <h2 id="автоматическая-группировка-batching" data-svelte-h="svelte-g6ur06"><a class="heading-link" title="Permalink" aria-hidden="true" href="#автоматическая-группировка-batching"><span>#</span></a>Автоматическая Группировка (Batching)</h2> <p data-svelte-h="svelte-1jk35by">React 19 расширяет автоматическую группировку на больше сценариев, включая промисы, обработчики нативных событий и временной интервал с <code>requestIdleCallback</code>. Это приводит к меньшему количеству повторных рендеров и улучшению производительности для приложений React.</p> <p data-svelte-h="svelte-xerk48">Для демонстрации эффекта автоматической группировки в React 19 и сравнения его с предыдущим поведением, рассмотрим пример, когда мы обновляем состояние в ответ на клик пользователя. В более ранних версиях React, без явного использования ReactDOM.unstable_batchedUpdates (для событий, не связанных с React, например, в асинхронных операциях), обновления состояния могли приводить к нескольким перерендерам.</p> <h3 id="как-было-раньше" data-svelte-h="svelte-1ownm9i"><a class="heading-link" title="Permalink" aria-hidden="true" href="#как-было-раньше"><span>#</span></a>Как было раньше</h3> <pre class="language-js"><!-- HTML_TAG_START --><code class="language-js"><span class="token keyword">function</span> <span class="token function">MyComponent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	<span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> setCount<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">const</span> <span class="token punctuation">[</span>flag<span class="token punctuation">,</span> setFlag<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

	<span class="token keyword">function</span> <span class="token function">handleClick</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token comment">// Представим, что это вызовы setState происходят в результате асинхронной операции</span>
		<span class="token comment">// или в обработчике событий, не управляемом React (например, внешний WebSocket).</span>
		<span class="token function">setCount</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">c</span><span class="token punctuation">)</span> <span class="token operator">=></span> c <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token function">setFlag</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">f</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator">!</span>f<span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token comment">// В более старых версиях React, каждый вызов setState приводил бы к отдельному рендеру,</span>
		<span class="token comment">// если не использовать unstable_batchedUpdates для явной группировки.</span>
	<span class="token punctuation">&#125;</span>

	<span class="token keyword">return</span> <span class="token punctuation">(</span>
		<span class="token operator">&lt;</span>div<span class="token operator">></span>
			<span class="token operator">&lt;</span>p<span class="token operator">></span>Счётчик<span class="token operator">:</span> <span class="token punctuation">&#123;</span>count<span class="token punctuation">&#125;</span><span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">></span>
			<span class="token operator">&lt;</span>p<span class="token operator">></span>Флаг<span class="token operator">:</span> <span class="token punctuation">&#123;</span>flag<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">></span>
			<span class="token operator">&lt;</span>button onClick<span class="token operator">=</span><span class="token punctuation">&#123;</span>handleClick<span class="token punctuation">&#125;</span><span class="token operator">></span>Обновить<span class="token operator">&lt;</span><span class="token operator">/</span>button<span class="token operator">></span>
		<span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span>
	<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span></code><!-- HTML_TAG_END --></pre> <p data-svelte-h="svelte-tzlsg2">В этом примере, без автоматической группировки, каждое обновление состояния (setCount и setFlag) могло приводить к отдельному рендеру в более старых версиях React. Это могло негативно сказаться на производительности, особенно в компонентах с большим количеством обновлений состояния.</p> <h3 id="с-автоматической-группировкой-в-react-19" data-svelte-h="svelte-czk9my"><a class="heading-link" title="Permalink" aria-hidden="true" href="#с-автоматической-группировкой-в-react-19"><span>#</span></a>С Автоматической Группировкой в React 19</h3> <p data-svelte-h="svelte-hc4810">В React 19 автоматическая группировка обновлений состояния расширена и на асинхронные операции, так что пример выше будет работать более эффективно “из коробки”:</p> <pre class="language-js"><!-- HTML_TAG_START --><code class="language-js"><span class="token comment">// Код не поменяется, тот же самый код будет работать, но React 19 автоматически оптимизирует и группирует обновления,</span>
<span class="token comment">// сокращая количество рендеров до одного.</span></code><!-- HTML_TAG_END --></pre> <p data-svelte-h="svelte-10g5jbj">Это значит, что в React 19, оба вызова <code>setState</code> в функции <code>handleClick</code> будут автоматически сгруппированы в один перерендер, независимо от того, происходят ли они в результате асинхронной операции или в обработчиках событий, не управляемых React. Это улучшение значительно облегчает разработку, снижая необходимость в ручном управлении группировками обновлений и способствуя более высокой производительности приложения.</p> <h2 id="серверные-компоненты" data-svelte-h="svelte-1b0c8am"><a class="heading-link" title="Permalink" aria-hidden="true" href="#серверные-компоненты"><span>#</span></a>Серверные Компоненты</h2> <p data-svelte-h="svelte-1kh6rc5">React 19 улучшает поддержку серверных компонентов, позволяя разработчикам создавать компоненты, которые рендерятся исключительно на сервере. Это сокращает размер JavaScript-бандла, отправляемого клиенту, улучшая время загрузки и производительность. Серверные компоненты могут беспрепятственно интегрироваться с клиентскими компонентами, позволяя разработчикам создавать более эффективные и динамичные приложения.</p> <h2 id="конкурентные-функции" data-svelte-h="svelte-1gtzax8"><a class="heading-link" title="Permalink" aria-hidden="true" href="#конкурентные-функции"><span>#</span></a>Конкурентные Функции</h2> <p data-svelte-h="svelte-19uodzf">Конкурентные функции в React — это набор возможностей, введённых для улучшения производительности и отзывчивости приложений за счёт более эффективного управления приоритетами обновлений и рендеринга.</p> <p data-svelte-h="svelte-1s57ewg">Эти функции позволяют React лучше использовать ресурсы браузера, выполняя работу в фоновом режиме, откладывая менее важные задачи и сосредотачиваясь на критически важных для пользователя действиях. Это позволяет приложениям оставаться отзывчивыми даже при выполнении тяжёлых вычислений или загрузке данных.</p> <h3 id="примеры-использования" data-svelte-h="svelte-13rjmre"><a class="heading-link" title="Permalink" aria-hidden="true" href="#примеры-использования"><span>#</span></a>Примеры Использования</h3> <p data-svelte-h="svelte-r6j73q">React позволяет использовать API, такие как <code>startTransition</code>, для указания задач, которые могут быть отложены без ущерба для восприятия пользователем отзывчивости интерфейса. Например:</p> <pre class="language-js"><!-- HTML_TAG_START --><code class="language-js"><span class="token keyword">import</span> <span class="token punctuation">&#123;</span> startTransition <span class="token punctuation">&#125;</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">MyComponent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	<span class="token keyword">const</span> <span class="token punctuation">[</span>input<span class="token punctuation">,</span> setInput<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">const</span> <span class="token punctuation">[</span>filteredData<span class="token punctuation">,</span> setFilteredData<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

	<span class="token keyword">function</span> <span class="token function">handleChange</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token keyword">const</span> nextInput <span class="token operator">=</span> e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
		<span class="token function">setInput</span><span class="token punctuation">(</span>nextInput<span class="token punctuation">)</span><span class="token punctuation">;</span>

		<span class="token comment">// Эта задача может быть выполнена асинхронно без блокировки основного потока,</span>
		<span class="token comment">// улучшая восприятие отзывчивости приложения.</span>
		<span class="token function">startTransition</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
			<span class="token keyword">const</span> nextFilteredData <span class="token operator">=</span> <span class="token function">expensiveFilterOperation</span><span class="token punctuation">(</span>nextInput<span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token function">setFilteredData</span><span class="token punctuation">(</span>nextFilteredData<span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">&#125;</span>

	<span class="token keyword">return</span> <span class="token punctuation">(</span>
		<span class="token operator">&lt;</span>div<span class="token operator">></span>
			<span class="token operator">&lt;</span>input value<span class="token operator">=</span><span class="token punctuation">&#123;</span>input<span class="token punctuation">&#125;</span> onChange<span class="token operator">=</span><span class="token punctuation">&#123;</span>handleChange<span class="token punctuation">&#125;</span> <span class="token operator">/</span><span class="token operator">></span>
			<span class="token punctuation">&#123;</span><span class="token comment">/* Отображение отфильтрованных данных */</span><span class="token punctuation">&#125;</span>
		<span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span>
	<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span></code><!-- HTML_TAG_END --></pre> <div class="callout-block info svelte-sxx0n0"><div class="icon-wrapper svelte-sxx0n0"><svg width="100%" height="100%" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 11.5V16.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 7.51L12.01 7.49889" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></div> С использованием конкурентного режима, React может решать, когда лучше всего рендерить обновления, не приводя к задержкам в важных для пользователя интеракциях.</div> <h3 id="конкурентные-функции-в-react---круто" data-svelte-h="svelte-eulwrs"><a class="heading-link" title="Permalink" aria-hidden="true" href="#конкурентные-функции-в-react---круто"><span>#</span></a>Конкурентные функции в React - круто?</h3> <p data-svelte-h="svelte-xi2yx8">Конкурентные функции в React предоставляют мощные инструменты для управления производительностью и отзывчивостью приложений. Они позволяют разработчикам более тонко управлять приоритетами задач, оптимизируя взаимодействие пользователя с приложением даже при высоких нагрузках. Внедрение этих методик в процесс разработки может способствовать созданию более плавных и приятных для пользователя приложений.</p> <h2 id="оптимизации-и-исправления-ошибок" data-svelte-h="svelte-a32oc6"><a class="heading-link" title="Permalink" aria-hidden="true" href="#оптимизации-и-исправления-ошибок"><span>#</span></a>Оптимизации и Исправления Ошибок</h2> <p data-svelte-h="svelte-1krxqss">React 19 включает различные оптимизации и исправления ошибок, направленные на улучшение опыта разработчиков и стабильности приложений.</p> <p data-svelte-h="svelte-q9irmf">Это включает улучшения в React DevTools, лучшую обработку ошибок и обновления в алгоритме согласования, чтобы сделать его более эффективным.</p> <h2 id="улучшения-suspense-и-ленивой-загрузки-lazy-loading" data-svelte-h="svelte-1rwdvud"><a class="heading-link" title="Permalink" aria-hidden="true" href="#улучшения-suspense-и-ленивой-загрузки-lazy-loading"><span>#</span></a>Улучшения Suspense и Ленивой Загрузки (lazy loading)</h2> <p data-svelte-h="svelte-1k3ofhm">Релиз приносит улучшения для <code>Suspense</code> и ленивой загрузки (на англ. lazy loading), упрощая разделение кода (на англ. code splitting) и ленивую загрузку компонентов.</p> <p data-svelte-h="svelte-qqdw3k">Это может значительно улучшить время начальной загрузки приложений, уменьшая количество кода, необходимого во время начальной загрузки.</p> <h2 id="улучшенный-опыт-разработчиков" data-svelte-h="svelte-13y4yd9"><a class="heading-link" title="Permalink" aria-hidden="true" href="#улучшенный-опыт-разработчиков"><span>#</span></a>Улучшенный Опыт Разработчиков</h2> <p data-svelte-h="svelte-1xuoid2">С обновлениями сообщений об ошибках, предупреждений и React DevTools, разработчики могут ожидать улучшенного опыта разработки.</p> <p data-svelte-h="svelte-lddriw">Эти изменения направлены на то, чтобы сделать отладку и разработку более интуитивно понятными и менее времязатратными.</p> <h2 id="документация" data-svelte-h="svelte-1jssbmf"><a class="heading-link" title="Permalink" aria-hidden="true" href="#документация"><span>#</span></a>Документация</h2> <p data-svelte-h="svelte-jkex9j">Команда React также сосредоточилась над улучшением документации и туториалов. Введение новых учебных ресурсов направлено на поддержку как новых, так и опытных разработчиков в создании React приложений.</p> <h2 id="заключение" data-svelte-h="svelte-lr9prh"><a class="heading-link" title="Permalink" aria-hidden="true" href="#заключение"><span>#</span></a>Заключение</h2> <p data-svelte-h="svelte-1arf5vu">Улучшения в React 19 предназначены для того, чтобы сделать React приложения более эффективными, проще в разработке и более производительными, чем раньше. Фокус на автоматической группировке, серверных компонентах, конкурентных функциях и оптимизациях отражает стремление React улучшить как опыт разработки, так и пользовательский опыт, что очень круто.</p>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/react-19-obzor.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/react-19-obzor.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/shopify-move-product-description</guid>
          <title>Как перенести описание товара в Shopify?</title>
          <description>Перенос описания товара может стать неплохим решением кастомизации вашего магазина. Например, если вы не хотите чтобы в правой колонке было много контента.</description>
          <link>https://devmoek.ru/shopify-move-product-description</link>
          <pubDate>Sat, 03 Feb 2024 21:55:15 +0000</pubDate>
          <category>shopify</category><category>how to</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/shopify-move-product-description">
                  читать на сайте
                </a>
              </strong>
            </div>

            <p data-svelte-h="svelte-ih64t2">Перенос описания товара может стать неплохим решением кастомизации вашего магазина. Например, если вы не хотите чтобы в правой колонке было много контента.</p> <iframe width="100%" height="350" src="https://www.youtube.com/embed/4XizQ0UvfEY?si=ZAUJfUfIyrCl0Mn6" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> <p data-svelte-h="svelte-ibi7bm">В этой статье мы перенесём описание под товар, конечный итог будет выглядеть вот так:</p> <p data-svelte-h="svelte-yxlbpb"><img src="https://shopifydevs.ru/wp-content/uploads/2024/01/image-1024x657.png" alt="демонстрация переноса товара под карточку на странице продукта в Shopify"></p> <p data-svelte-h="svelte-w408z2">Как вы можете заметить, описание находится под товаром, что позволяет справа разместить больше контента, например, Upsell блок для отображения похожих товаров.</p> <h2 id="что-такое-upsell" data-svelte-h="svelte-11rxm5v"><a class="heading-link" title="Permalink" aria-hidden="true" href="#что-такое-upsell"><span>#</span></a>Что такое Upsell?</h2> <p data-svelte-h="svelte-nnvkbv"><strong>Upsell (продажа дополнительных товаров или услуг)</strong> – это маркетинговая стратегия, при которой продавец предлагает покупателю более дорогой продукт, улучшение или дополнение к тому, что уже выбрано или куплено клиентом. Цель этой стратегии – увеличить среднюю стоимость покупки, предлагая покупателям более высококлассные или дополнительные товары или услуги.</p> <h2 id="удаляем-блок-с-описанием" data-svelte-h="svelte-fygq0m"><a class="heading-link" title="Permalink" aria-hidden="true" href="#удаляем-блок-с-описанием"><span>#</span></a>Удаляем блок с описанием</h2> <p data-svelte-h="svelte-1wl8qw4">Для начала нужно удалить блок с описанием который у нас изначально есть в секцие с товаром. На скриншоте ниже я скрыл этот блок:
<img src="https://shopifydevs.ru/wp-content/uploads/2024/01/image-1.png" alt="удаляем или скрываем блок description из секции информации о товаре"></p> <h2 id="добавляем-секцию-rich-text" data-svelte-h="svelte-dwt7oa"><a class="heading-link" title="Permalink" aria-hidden="true" href="#добавляем-секцию-rich-text"><span>#</span></a>Добавляем секцию Rich Text</h2> <p data-svelte-h="svelte-13982qc">Она нам понадобится чтобы <strong>динамически</strong> отображать текст формата:</p> <pre class="language-undefined"><!-- HTML_TAG_START --><code class="language-undefined">[НАЗВАНИЕ ПРОДУКТА] - Description</code><!-- HTML_TAG_END --></pre> <p data-svelte-h="svelte-hh13fk">Это позволит не создавать секцию под каждый товар. В данной секцие мы будем подставлять название продукта, а Description будет статическим значением.</p> <div class="callout-block warning svelte-sxx0n0"><div class="icon-wrapper svelte-sxx0n0"><svg width="100%" height="100%" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 7L12 13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 17.01L12.01 16.9989" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></div> Если у вас мультиязычный магазин, избегайте использование статических данных, например, как тут мы используем слово &quot;Description&quot;</div> <p data-svelte-h="svelte-1i6huho">Выводить описание вместе с этой секцией необязательно. Если вы не желаете делать таким образом, то переходите дальше.</p> <h2 id="добавляем-секцию-custom-liquid" data-svelte-h="svelte-1j6ce1q"><a class="heading-link" title="Permalink" aria-hidden="true" href="#добавляем-секцию-custom-liquid"><span>#</span></a>Добавляем секцию Custom Liquid</h2> <p data-svelte-h="svelte-1rpntah">Следующий шаг – добавить новую секцию под названием Custom Liquid. Эта секция позволяет вставлять liquid код. Она нам нужна чтобы отобразить описание.</p> <h3 id="что-такое-liquid" data-svelte-h="svelte-zis7w2"><a class="heading-link" title="Permalink" aria-hidden="true" href="#что-такое-liquid"><span>#</span></a>Что такое liquid?</h3> <p data-svelte-h="svelte-1q6wqem"><strong>Liquid</strong> – это шаблонизатор, который используется для создания динамических веб-страниц. Разработан компанией Shopify и в основном используется в их электронной коммерческой платформе.</p> <p data-svelte-h="svelte-pmi5ke">Основная цель Liquid заключается в обеспечении гибкости и удобства для разработчиков при создании настраиваемых шаблонов, которые могут отображать различный контент в зависимости от контекста или данных пользователя.</p> <h2 id="отображение-описания-товара" data-svelte-h="svelte-19facdb"><a class="heading-link" title="Permalink" aria-hidden="true" href="#отображение-описания-товара"><span>#</span></a>Отображение описания товара</h2> <p data-svelte-h="svelte-o7mm8q">Для отображения товара мы будем использовать следующий кусок кода:</p> <pre class="language-html"><!-- HTML_TAG_START --><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>page-width<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>&#123;&#123; product.description &#125;&#125;<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></code><!-- HTML_TAG_END --></pre> <p data-svelte-h="svelte-9aiy7l">Так как в примере используете тема Dawn, блок описания оборачивается в контейнер с классом page-width.</p> <p data-svelte-h="svelte-1ilocjq">Такой класс есть также у тем: Ride, Refresh, Sense, Origin, Craft, Taste, Studio, Crave, Publisher, Colorblock.</p> <p data-svelte-h="svelte-ayhe4n">Это нужно для того чтобы описание не “прилепало” к границам устройства. Если вы используете другую тему, у вас класс, отвечающий за ограничение ширины блока, может быть иной.</p> <p data-svelte-h="svelte-5waonz">Также, могут быть случаи, когда оборачивать описание в контейнер может быть необязательно, в таком случае отображение описания будет выглядеть вот так:</p> <pre class="language-undefined"><!-- HTML_TAG_START --><code class="language-undefined">&#123;&#123; product.description &#125;&#125;</code><!-- HTML_TAG_END --></pre> <h2 id="заключение" data-svelte-h="svelte-lr9prh"><a class="heading-link" title="Permalink" aria-hidden="true" href="#заключение"><span>#</span></a>Заключение</h2> <p data-svelte-h="svelte-12dv5f6">Теперь вы умеете отображать описание товара под товаром. В этой статье мы рассмотрели один из многих вариантов иного от шаблонного отображения описания.</p> <h3 id="статья-была-полезна" data-svelte-h="svelte-nw68d8"><a class="heading-link" title="Permalink" aria-hidden="true" href="#статья-была-полезна"><span>#</span></a>Статья была полезна?</h3> <p data-svelte-h="svelte-i0u10v">Если статья была полезна или вам понравилась - поделитесь с друзьями! На этом сайте нет рекламы и он ведётся на энтузиазме, любое упоминание повышает шанс на улыбку у автора.</p>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/move-shopify-product-description.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/move-shopify-product-description.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/nuxt-jumping-footer</guid>
          <title>Как пофиксить прыгающий подвал в Nuxt.js?</title>
          <description>Иногда при работе с Vue.js или Nuxt.js возникает баг. При переходе на разные страницы веб-приложения, подвал приложения 'подскакивает' к шапке. Как решить такой баг?</description>
          <link>https://devmoek.ru/nuxt-jumping-footer</link>
          <pubDate>Mon, 01 Jan 2024 21:55:15 +0000</pubDate>
          <category>веб разработка</category><category>nuxt</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/nuxt-jumping-footer">
                  читать на сайте
                </a>
              </strong>
            </div>

            <p data-svelte-h="svelte-91979h">Иногда при работе с Vue.js или Nuxt.js возникает баг. При переходе на разные страницы веб-приложения, подвал приложения “подскакивает” к шапке. Это решается довольно просто, в этом посте я показал решение этого бага и возможные причины его появления в вашем приложение.</p> <h2 id="youtube-видео" data-svelte-h="svelte-fa8vx5"><a class="heading-link" title="Permalink" aria-hidden="true" href="#youtube-видео"><span>#</span></a>YouTube видео</h2> <iframe width="100%" height="415" src="https://www.youtube.com/embed/eVZKrE68CCE?si=WtygtHtx-5XXLlVI" title="YouTube видео плейер" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> <h2 id="в-этом-посте" data-svelte-h="svelte-127dwbj"><a class="heading-link" title="Permalink" aria-hidden="true" href="#в-этом-посте"><span>#</span></a>В этом посте</h2> <ul data-svelte-h="svelte-axjwal"><li>Почему при переходе на разные страницы в Nuxt.js приложение футер скачет?</li> <li>Причины прыгающего подвала к шапке сайта при переходе на разные страницы</li> <li>Фикс прыгающего подвала в Nuxt.js</li></ul> <h2 id="причины-появления-прыгающего-эффекта" data-svelte-h="svelte-1q0xv3q"><a class="heading-link" title="Permalink" aria-hidden="true" href="#причины-появления-прыгающего-эффекта"><span>#</span></a>Причины появления “прыгающего” эффекта</h2> <h3 id="css-стили" data-svelte-h="svelte-ofw4tu"><a class="heading-link" title="Permalink" aria-hidden="true" href="#css-стили"><span>#</span></a>CSS стили</h3> <p data-svelte-h="svelte-stzrob">Проблема может быть связана с CSS стилями, применяемыми к компонентам Header, Footer или даже к <code>&lt;NuxtPage /&gt;</code>. Если для этих элементов заданы определенные стили (например, абсолютное или фиксированное позиционирование), это может привести к тому, что футер будет отображаться неправильно. Проверьте и убедитесь, что стили не конфликтуют друг с другом.</p> <p data-svelte-h="svelte-f1u4x7">Убедитесь, что у элементов Header, Footer, и <code>&lt;NuxtPage /&gt;</code> заданы корректные высоты. Если высота этих элементов не контролируется должным образом, это может привести к тому, что футер окажется под шапкой.</p> <h3 id="js-скрипт" data-svelte-h="svelte-68wsbg"><a class="heading-link" title="Permalink" aria-hidden="true" href="#js-скрипт"><span>#</span></a>JS скрипт</h3> <p data-svelte-h="svelte-1vheswh">Если вы используете JavaScript или Vue Lifecycle Hooks для динамического изменения стилей или классов, это также может повлиять на расположение футера.</p> <h3 id="конфликт-компонентов" data-svelte-h="svelte-1w10p43"><a class="heading-link" title="Permalink" aria-hidden="true" href="#конфликт-компонентов"><span>#</span></a>Конфликт компонентов</h3> <p data-svelte-h="svelte-g5oa5w">Если вы подключаете какие-либо компоненты на в файле <code>app.vue</code>, то это тоже может повлиять на шапку или подвал веб-приложения.</p> <h3 id="html-ошибки" data-svelte-h="svelte-1nxgc9v"><a class="heading-link" title="Permalink" aria-hidden="true" href="#html-ошибки"><span>#</span></a>HTML ошибки</h3> <p data-svelte-h="svelte-8punfe">Проверьте, нет ли ошибок в вашем HTML, которые могут привести к непредвиденному поведению макета. Например, незакрытые теги.</p> <h2 id="решение" data-svelte-h="svelte-1ke96xp"><a class="heading-link" title="Permalink" aria-hidden="true" href="#решение"><span>#</span></a>Решение</h2> <p data-svelte-h="svelte-i9xnmf">Если всё из вышеперечисленного не помогло решить проблему, то попробуйте обернуть <code>&lt;NuxtPage /&gt;</code> в <code>&lt;div&gt;</code>.</p> <pre class="language-vue"><!-- HTML_TAG_START --><code class="language-vue">&lt;template&gt;
	&lt;NuxtLayout&gt;
		&lt;Header /&gt;
		+
		&lt;div&gt;
			&lt;NuxtPage /&gt;
			+
		&lt;/div&gt;
		&lt;Footer /&gt;
	&lt;/NuxtLayout&gt;
&lt;/template&gt;</code><!-- HTML_TAG_END --></pre> <h2 id="заключение" data-svelte-h="svelte-lr9prh"><a class="heading-link" title="Permalink" aria-hidden="true" href="#заключение"><span>#</span></a>Заключение</h2> <p data-svelte-h="svelte-aicqa4">Теперь вы знаете как решить проблему прыгающего футера при переходе на разные страницы в Nuxt.js. Надеюсь этот пост был вам полезен!</p>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/фикс-прыгающего-футера-nuxt-3.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/фикс-прыгающего-футера-nuxt-3.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/top-10-freelance-platforms</guid>
          <title>Топ 10 Фриланс Бирж</title>
          <description>Вы ищете возможности работы фрилансером? Существует множество веб-сайтов, которые предоставляют фрилансерам площадки для общения с клиентами и поиска работы.</description>
          <link>https://devmoek.ru/top-10-freelance-platforms</link>
          <pubDate>Tue, 26 Dec 2023 21:55:15 +0000</pubDate>
          <category>фриланс</category><category>топ 10</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/top-10-freelance-platforms">
                  читать на сайте
                </a>
              </strong>
            </div>

            <div class="callout-block info svelte-sxx0n0"><div class="icon-wrapper svelte-sxx0n0"><svg width="100%" height="100%" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 11.5V16.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 7.51L12.01 7.49889" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></div> Некоторые ссылки на площадки реферальные, если вы зарегистрируетесь по ним, я получу бонус.</div> <p data-svelte-h="svelte-mxr7bj">Вы ищете возможности работы фрилансером? Существует множество веб-сайтов, которые предоставляют фрилансерам платформу для общения с клиентами и поиска работы. Фрилансеру может быть сложно найти работу, особенно в самом начале.</p> <h2 id="содержание" data-svelte-h="svelte-1aprgkl"><a class="heading-link" title="Permalink" aria-hidden="true" href="#содержание"><span>#</span></a>Содержание</h2> <ul data-svelte-h="svelte-5eargn"><li><a href="#%D0%B0%D0%BF%D0%B2%D0%BE%D1%80%D0%BA-upwork">Апворк (Upwork)</a></li> <li><a href="#%D1%84%D1%80%D0%B8%D0%BB%D0%B0%D0%BD%D1%81%D0%B5%D1%80-freelancer">Фрилансер (Freelancer)</a></li> <li><a href="#%D1%84%D0%B0%D0%B9%D0%B2%D0%B5%D1%80-fiverr">Файвер (Fiverr)</a></li> <li><a href="#%D1%82%D0%BE%D0%BF%D1%82%D0%B0%D0%BB-toptal">Топтал (Toptal)</a></li> <li><a href="#%D0%B3%D1%83%D1%80%D1%83-guru">Гуру (Guru)</a></li> <li><a href="#99-%D0%B4%D0%B8%D0%B7%D0%B0%D0%B9%D0%BD%D0%BE%D0%B2-99-designs">99 дизайнов (99 designs)</a></li> <li><a href="#%D0%BB%D1%8E%D0%B4%D0%B8-%D0%B2-%D1%87%D0%B0%D1%81-peopleperhour">Люди в час (peoplePerHour)</a></li> <li><a href="#%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%B0-contra">Контра (Contra)</a></li> <li><a href="#%D0%BB%D0%B5%D0%B3%D0%BA%D0%BE-%D0%BD%D0%B0%D0%BD%D1%8F%D1%82-simplyhired">Легко Нанят (SimplyHired)</a></li> <li><a href="#%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%BB%D0%B8%D0%B2%D1%8B%D0%B9-%D0%BA%D1%80%D0%BE%D0%BB%D0%B8%D0%BA-taskrabbit">Задачливый Кролик (TaskRabbit)</a></li></ul> <p data-svelte-h="svelte-tzbo4a">К счастью, существует множество сайтов для фрилансеров, которые могут помочь вам найти идеальную работу. Вот 10 лучших сайтов для фрилансеров, которые вам стоит посетить.</p> <h2 id="апворк-upwork" data-svelte-h="svelte-1vk796f"><a class="heading-link" title="Permalink" href="https://upwork.com/" target="_blank">Апворк (Upwork)</a></h2> <p data-svelte-h="svelte-1edvjcr">Upwork — один из крупнейших сайтов для фрилансеров с огромным количеством объявлений о вакансиях. Он идеально подходит для писателей, дизайнеров, разработчиков и маркетологов. Сайт предлагает множество вакансий с различной структурой оплаты, включая проекты с почасовой оплатой и с фиксированной ставкой. Он также имеет функцию Upwork Pro, которая связывает предприятия с фрилансерами с самым высоким рейтингом для крупномасштабных проектов.</p> <p data-svelte-h="svelte-1ewfeof">Upwork — отличный выбор для начинающих фрилансеров или для тех, кто хочет расширить свою клиентскую базу.
<img src="https://blog.devmoek.com/content/images/size/w1000/2023/12/upwork.jpg" alt="главная страница фриланс площадки Upwork"></p> <h2 id="фрилансер-freelancer" data-svelte-h="svelte-17lu8ai"><a class="heading-link" title="Permalink" href="https://freelancer.com/" target="_blank">Фрилансер (Freelancer)</a></h2> <p data-svelte-h="svelte-59edtj">Freelancer имеет удобный интерфейс и предоставляет вакансии в различных категориях, включая написание, дизайн и программирование. Эта платформа предлагает уникальную функцию под названием «Контесты», где клиенты могут проводить конкурсы для конкретного проекта, а фрилансеры могут отправлять свои работы, чтобы выиграть денежный приз. У Freelancer также есть мобильное приложение, которое позволяет фрилансерам искать работу и управлять своими профилями на ходу.
<img src="https://blog.devmoek.com/content/images/size/w1000/2023/12/screenshot-www.freelancer.com-2023.12.04-10_56_15.png" alt="главная страница фриланс площадки Freelancer"></p> <h2 id="файвер-fiverr" data-svelte-h="svelte-nev6bj"><a class="heading-link" title="Permalink" href="https://www.fiverr.com/pe/aBpQDG" target="_blank">Файвер (Fiverr)</a></h2> <p data-svelte-h="svelte-18ojrmd">Fiverr — отличная платформа для фрилансеров, которые специализируются на творческих услугах, таких как графический дизайн, редактирование видео и копирайтинг. Как следует из названия, Fiverr начинался как платформа, где фрилансеры могли предлагать свои услуги за 5 долларов. Однако сайт развился, и теперь фрилансеры могут устанавливать свои собственные расценки. Fiverr также имеет функцию под названием «Гиги», которая позволяет фрилансерам предлагать клиентам готовые услуги.
<img src="https://blog.devmoek.com/content/images/size/w1000/2023/12/Screenshot-2023-12-04-at-10-57-08-Find-the-best-global-talent.png" alt="главная страница фриланс площадки Fiverr"></p> <h2 id="топтал-toptal" data-svelte-h="svelte-1lsnrlm"><a class="heading-link" title="Permalink" href="https://www.toptal.com/" target="_blank">Топтал (Toptal)</a></h2> <p data-svelte-h="svelte-1mlh5fx">Toptal — эксклюзивная платформа, предоставляющая доступ к лучшим фрилансерам отрасли. Идеально подходит для бизнеса, которому нужна качественная работа.</p> <p data-svelte-h="svelte-a3rf34">Toptal имеет строгий процесс отбора, который гарантирует, что на платформу будут приняты только 3% лучших фрилансеров. Это означает, что клиенты могут быть уверены, что работают с лучшими из лучших. Toptal также предлагает услуги по управлению проектами и координации команды, что делает его универсальным сервисом для компаний, желающих передать свою работу на аутсорсинг.
<img src="https://blog.devmoek.com/content/images/size/w1000/2023/12/Screenshot-2023-12-04-at-10-57-42-We-connect-expertly-vetted-talent-with-world-class-clients.png" alt="главная страница фриланс площадки Toptal"></p> <h2 id="гуру-guru" data-svelte-h="svelte-g8cd4l"><a class="heading-link" title="Permalink" href="https://www.guru.com/" target="_blank">Гуру (Guru)</a></h2> <p data-svelte-h="svelte-17t9mrt">Guru предоставляет возможности трудоустройства фрилансерам в различных категориях, таких как веб-разработка, дизайн, писательство и маркетинг. На сайте есть функция SafePay, которая позволяет клиентам вносить средства на целевой депозитный счет, а платеж производится только тогда, когда проект завершен к удовлетворению клиента. У Guru также есть инструмент для совместной работы, который позволяет фрилансерам и клиентам общаться и обмениваться файлами в режиме реального времени.</p> <p data-svelte-h="svelte-164pwbp"><img src="https://blog.devmoek.com/content/images/size/w1000/2023/12/Screenshot-2023-12-04-at-10-58-18-Guru.com---Find-and-Hire-Expert-Freelancers.png" alt="главная страница фриланс площадки Guru"></p> <h2 id="99-дизайнов-99-designs" data-svelte-h="svelte-qrj1d6"><a class="heading-link" title="Permalink" href="https://99designs.com/" target="_blank">99 дизайнов (99 designs)</a></h2> <p data-svelte-h="svelte-yuid8">99designs — это платформа, предназначенная исключительно для дизайнеров. Он предоставляет возможности графическим дизайнерам, дизайнерам логотипов и веб-дизайнерам.</p> <p data-svelte-h="svelte-wtp6jd">На сайте есть уникальная функция «Конкурсы», где клиенты могут проводить конкурсы на конкретный дизайн-проект, а фрилансеры могут отправлять свои работы и получать денежный приз. В 99designs также есть функция «Проекты», где клиенты могут работать один на один с фрилансером для создания индивидуального дизайна.
<img src="https://blog.devmoek.com/content/images/size/w1000/2023/12/Screenshot-2023-12-04-at-10-58-48-Logos-Web-Graphic-Design---More.-99designs.png" alt="главная страница фриланс площадки 99 designs"></p> <h2 id="люди-в-час-peopleperhour" data-svelte-h="svelte-dr3z0y"><a class="heading-link" title="Permalink" href="https://www.peopleperhour.com/" target="_blank">Люди в час (peoplePerHour)</a></h2> <p data-svelte-h="svelte-1k9gga8">PeoplePerHour — это британский веб-сайт для фрилансеров, который предоставляет возможности трудоустройства фрилансерам по всему миру. Он идеально подходит для писателей, дизайнеров и разработчиков.</p> <p data-svelte-h="svelte-32zisy">На сайте есть функция «Почасовые часы», где фрилансеры могут предлагать свои услуги по фиксированной цене. PeoplePerHour также имеет мобильное приложение, которое позволяет фрилансерам искать работу и управлять своими профилями на ходу.
<img src="https://blog.devmoek.com/content/images/size/w1000/2023/12/Screenshot-2023-12-04-at-10-59-13-PeoplePerHour.com---Hire-Freelancers-Online---Find-Freelance-Work.png" alt="главная страница фриланс площадки peoplePerHour"></p> <h2 id="статья-полезна" data-svelte-h="svelte-ojzyt9"><a class="heading-link" title="Permalink" aria-hidden="true" href="#статья-полезна"><span>#</span></a>Статья полезна?</h2> <p data-svelte-h="svelte-1m1xpbe">Вы можете поддержать автора, если статья вам помогла и была полезной.</p> <a href="https://www.paypal.com/paypalme/majersas" target="_blank" rel="noopener noreferrer" class="button style--solid size--medium color--primary  svelte-hsaxku" data-sveltekit-preload-data> Поддержать автора через PayPal</a> <p data-svelte-h="svelte-1kxyahe">PayPal не работает? Не проблема.</p> <a href="https://donate.stream/myers" target="_blank" rel="noopener noreferrer" class="button style--solid size--medium color--primary  svelte-hsaxku" data-sveltekit-preload-data> Поддержать автора</a> <h2 id="контра-contra" data-svelte-h="svelte-le7b9m"><a class="heading-link" title="Permalink" href="https://contra.com/" target="_blank">Контра (Contra)</a></h2> <p data-svelte-h="svelte-j95bk7">На Contra фрилансеры могут создать профиль, в котором подчеркнут их навыки и опыт, искать вакансии и подавать заявки на проекты, соответствующие их опыту. Платформа охватывает широкий спектр отраслей, включая дизайн, разработку, написание текстов, маркетинг и многое другое.</p> <p data-svelte-h="svelte-10tcnit">Contra также предлагает такие функции, как условное депонирование платежей, инструменты управления проектами и разрешение споров, чтобы обеспечить плавные и безопасные транзакции между фрилансерами и клиентами.</p> <p data-svelte-h="svelte-8camww"><img src="https://blog.devmoek.com/content/images/size/w1000/2023/12/Screenshot-2023-12-04-at-10-59-40-Freelance-Marketplace-Commission-Free.png" alt="главная страница фриланс площадки Contra"></p> <h2 id="легко-нанят-simplyhired" data-svelte-h="svelte-1n8yjpb"><a class="heading-link" title="Permalink" href="https://www.simplyhired.com/" target="_blank">Легко Нанят (SimplyHired)</a></h2> <p data-svelte-h="svelte-1m9qhog">SimplyHired — это система поиска работы, которая предоставляет возможности трудоустройства фрилансерам в различных категориях, таких как писательство, дизайн и программирование.</p> <p data-svelte-h="svelte-4c97pq">На сайте есть функция «Оценщик зарплат», которая позволяет фрилансерам видеть среднюю зарплату на конкретной должности в их области. У SimplyHired также есть мобильное приложение, которое позволяет фрилансерам искать работу и управлять своими профилями на ходу.
<img src="https://blog.devmoek.com/content/images/size/w1000/2023/12/Screenshot-2023-12-04-at-11-00-08-Job-Search-Engine-SimplyHired.png" alt="главная страница сайта SimplyHired"></p> <h2 id="задачливый-кролик-taskrabbit" data-svelte-h="svelte-yril6y"><a class="heading-link" title="Permalink" href="https://www.taskrabbit.com/" target="_blank">Задачливый Кролик (TaskRabbit)</a></h2> <p data-svelte-h="svelte-ce153m">TaskRabbit — это платформа, которая предоставляет возможности фрилансерам, специализирующимся на случайных работах, таких как уборка, переезд и услуги разнорабочих.</p> <p data-svelte-h="svelte-4goayp">На сайте есть функция «Мгновенный подбор», с помощью которой фрилансеры могут получать запросы о работе в режиме реального времени. TaskRabbit также имеет мобильное приложение, которое позволяет фрилансерам управлять своими профилями и получать запросы о работе на ходу.
<img src="https://blog.devmoek.com/content/images/size/w1000/2023/12/Screenshot-2023-12-04-at-11-00-31-Taskrabbit-Same-Day-Handyman-Moving---Mounting-Services.png" alt="главная страница фриланс площадки TaskRabbit"></p> <h2 id="заключение" data-svelte-h="svelte-lr9prh"><a class="heading-link" title="Permalink" aria-hidden="true" href="#заключение"><span>#</span></a>Заключение</h2> <p data-svelte-h="svelte-1ozrq5i">Если вы работаете из дома и ищете для себя новые возможности, эти 10 сайтов помогут вам найти идеальную работу. Каждая платформа имеет свои уникальные функции и преимущества, поэтому стоит проверить их, чтобы понять, какая из них соответствует вашим потребностям.</p> <p data-svelte-h="svelte-1k647fs">Независимо от того, являетесь ли вы дизайнером, разработчиком или маркетологом, существует платформа, которая поможет вам достичь ваших целей фрилансера. Имейте в виду, что построение успешной карьеры фрилансера требует времени и усилий, но с правильной платформой вы сможете найти качественных клиентов и построить успешную карьеру.</p> <h3 id="неуверены-с-чего-начать" data-svelte-h="svelte-1ahgrd5"><a class="heading-link" title="Permalink" aria-hidden="true" href="#неуверены-с-чего-начать"><span>#</span></a>Неуверены с чего начать?</h3> <a href="https://cal.com/devmoek" target="_blank" rel="noopener noreferrer" class="button style--solid size--medium color--primary  svelte-hsaxku" data-sveltekit-preload-data> Заказать консультацию</a> <p data-svelte-h="svelte-1qzdue3">Консультация проходит в Zoom тет-а-тет. Если у вас есть какие-либо вопросы или сложности, я вам помогу.</p>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/top-10-freelance-ploshadok.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/top-10-freelance-ploshadok.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/header-footer-nuxt3</guid>
          <title>Как добавить Шапку и Подвал в Nuxt 3</title>
          <description>Шапка и Подвал подобны подставкам для книг на веб-странице — они красиво обрамляют все и сохраняют целостность. В Nuxt 3 Шапку и Подвал можно легко создать, используя особый способ создания вещей, называемых «компонентами».</description>
          <link>https://devmoek.ru/header-footer-nuxt3</link>
          <pubDate>Wed, 20 Dec 2023 21:55:15 +0000</pubDate>
          <category>nuxt</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/header-footer-nuxt3">
                  читать на сайте
                </a>
              </strong>
            </div>

            <p data-svelte-h="svelte-nh5jys"><strong>Шапка (Header)</strong> и <strong>Подвал (Footer)</strong> подобны подставкам для книг на веб-странице — они красиво обрамляют все и сохраняют целостность. В Nuxt 3 Шапку и Подвал можно легко создать, используя особый способ создания вещей, называемых «компонентами».</p> <p data-svelte-h="svelte-uh8ita">Также мы исправим ошибку, когда вы могли видеть, что после перехода между страницами футер «прыгает».</p> <h2 id="понимание-компонентной-архитектуры-nuxt-3" data-svelte-h="svelte-1sc3brl"><a class="heading-link" title="Permalink" aria-hidden="true" href="#понимание-компонентной-архитектуры-nuxt-3"><span>#</span></a>Понимание компонентной архитектуры Nuxt 3</h2> <p data-svelte-h="svelte-hbs7t4">Nuxt 3 — это разбиение вещей на более мелкие части, называемые «компонентами». Это немного похоже на сборку из LEGO: вы создаете разные детали и соединяете их вместе, чтобы получилось что-то крутое. Верхние и нижние колонтитулы похожи на специальные кубики Lego, которые можно использовать снова и снова.</p> <h2 id="использование-header-и-footer-компонентов" data-svelte-h="svelte-lcm8td"><a class="heading-link" title="Permalink" aria-hidden="true" href="#использование-header-и-footer-компонентов"><span>#</span></a>Использование Header и Footer компонентов</h2> <p data-svelte-h="svelte-qor2af">Как только верхний и нижний колонтитулы будут готовы, мы заставим их отображаться на всех страницах с помощью макета. Или, если хотите, вы можете выбрать, где оно будет отображаться — например, на некоторых страницах, а не на других. В этом случае вам нужно будет создать разные макеты.</p> <h2 id="создание-макета-по-умолчанию" data-svelte-h="svelte-k0729p"><a class="heading-link" title="Permalink" aria-hidden="true" href="#создание-макета-по-умолчанию"><span>#</span></a>Создание макета по умолчанию</h2> <p data-svelte-h="svelte-zrudy4">В моем приложении мне не нужны разные макеты. У меня будет только один под названием <code>default.vue</code>. Итак, создайте папку макетов в корневом каталоге вашего проекта и создайте файл <code>default.vue</code>. В этом файле у нас будет этот фрагмент кода:</p> <pre class="language-svelte"><!-- HTML_TAG_START --><code class="language-svelte"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">></span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span>
		<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>slot</span> <span class="token punctuation">/></span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">></span></span></code><!-- HTML_TAG_END --></pre> <p data-svelte-h="svelte-nyfrcc">Как только мы закончили с макетом, нам нужно сделать его видимым на странице — добавьте макет в файл <code>app.vue</code> следующим образом:</p> <pre class="language-svelte"><!-- HTML_TAG_START --><code class="language-svelte"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">></span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NuxtLayout</span><span class="token punctuation">></span></span>
		<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Header</span> <span class="token punctuation">/></span></span>
		<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NuxtPage</span> <span class="token punctuation">/></span></span>
		<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Footer</span> <span class="token punctuation">/></span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>NuxtLayout</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">></span></span></code><!-- HTML_TAG_END --></pre> <div class="callout-block info svelte-sxx0n0"><div class="icon-wrapper svelte-sxx0n0"><svg width="100%" height="100%" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 11.5V16.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 7.51L12.01 7.49889" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></div> Я предполагаю, что в вашем проекте уже есть компоненты Шапки и Подвала.</div> <h2 id="поиск-неисправностей" data-svelte-h="svelte-1g04z0j"><a class="heading-link" title="Permalink" aria-hidden="true" href="#поиск-неисправностей"><span>#</span></a>Поиск неисправностей</h2> <p data-svelte-h="svelte-w2soks">Если вы вставляете приведенный выше код в свой проект и Футер «перепрыгивает» в верхнюю часть страницы при переходе между страницами, это потому, что нам нужно сделать нашу страницу уникальным узлом. Для этого нам нужно поместить наш <code>&lt;NuxtPage /&gt;</code> в <code>div</code>.</p> <pre class="language-svelte"><!-- HTML_TAG_START --><code class="language-svelte"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">></span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NuxtLayout</span><span class="token punctuation">></span></span>
		<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Header</span> <span class="token punctuation">/></span></span>
		+ <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span>
			<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NuxtPage</span> <span class="token punctuation">/></span></span>
		+ <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
		<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Footer</span> <span class="token punctuation">/></span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>NuxtLayout</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">></span></span></code><!-- HTML_TAG_END --></pre> <p data-svelte-h="svelte-16r0ehs">Теперь этот эффект сбоя должен исчезнуть.</p> <h2 id="заключение" data-svelte-h="svelte-lr9prh"><a class="heading-link" title="Permalink" aria-hidden="true" href="#заключение"><span>#</span></a>Заключение</h2> <p data-svelte-h="svelte-qxz3me">Хэдер и Футер могут показаться мелочами, но они очень важны для того, чтобы веб-сайт выглядел правильно. С Nuxt 3 можно легко создавать эти детали и использовать их снова и снова.</p>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/shapka-podval-nuxt3.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/shapka-podval-nuxt3.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/shopify-cart-api</guid>
          <title>Shopify Cart API - Добавляем несколько товаров в корзину</title>
          <description>Чтобы добавить в корзину несколько товаров, вам необходимо отправить в Cart API объект items с идентификатором(id) продукта и количеством(quantities) товара.</description>
          <link>https://devmoek.ru/shopify-cart-api</link>
          <pubDate>Wed, 29 Nov 2023 21:55:15 +0000</pubDate>
          <category>shopify</category><category>shopify разработка</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/shopify-cart-api">
                  читать на сайте
                </a>
              </strong>
            </div>

            <h2 id="содержание" data-svelte-h="svelte-1aprgkl"><a class="heading-link" title="Permalink" aria-hidden="true" href="#содержание"><span>#</span></a>Содержание</h2> <ul data-svelte-h="svelte-16c712l"><li><a href="#%D1%81%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5">Содержание</a></li> <li><a href="#%D0%BF%D1%80%D0%B5%D0%B4%D0%B8%D1%81%D0%BB%D0%BE%D0%B2%D0%B8%D0%B5">Предисловие</a></li> <li><a href="#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F">Пример использования</a></li> <li><a href="#cart-api">Cart API</a> <ul><li><a href="#%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%82%D0%BE%D0%B2%D0%B0%D1%80%D0%B0">Добавление товара</a></li> <li><a href="#%D0%BE%D1%82%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D1%8F%D0%B5%D0%BC%D1%8B%D0%B9-%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82">Отправляемый объект</a></li> <li><a href="#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80-fetch-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%B0">Пример fetch запроса</a></li></ul></li> <li><a href="#%D0%B7%D0%B0%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5">Заключение</a></li> <li><a href="#%D1%80%D0%B5%D1%81%D1%83%D1%80%D1%81%D1%8B">Ресурсы</a></li></ul> <h2 id="предисловие" data-svelte-h="svelte-1ras718"><a class="heading-link" title="Permalink" aria-hidden="true" href="#предисловие"><span>#</span></a>Предисловие</h2> <p data-svelte-h="svelte-36huf1">Недавно я писал конфигуратор в Shopify и решил поделиться тем, как добавить несколько товаров в Шопифай корзину. Я находил не так много материалов по этому вопросу, тем более на русском языке.</p> <h2 id="пример-использования" data-svelte-h="svelte-1spycrz"><a class="heading-link" title="Permalink" aria-hidden="true" href="#пример-использования"><span>#</span></a>Пример использования</h2> <p data-svelte-h="svelte-lltlqa">Прикрепляю скринкаст того, что можно сделать при помощи этого. Но применений довольно много, не только конфигуратор. В скринкасте я добавил 6 товаров по одному клику на «Add to cart» кнопку. Но до лимита в количестве добавляемых товаров я не дошёл, может их и нет.</p> <iframe width="100%" height="400" src="https://www.youtube.com/embed/0_8AF4msVpg?si=kyrESdU6-GaoEOR_" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> <h2 id="cart-api" data-svelte-h="svelte-zzckpx"><a class="heading-link" title="Permalink" aria-hidden="true" href="#cart-api"><span>#</span></a>Cart API</h2> <p data-svelte-h="svelte-tc205y">Сначала давайте разберёмся, что такое Cart API.</p> <p data-svelte-h="svelte-g220ta"><em>API корзины позволяет расширению пользовательского интерфейса взаимодействовать с содержимым корзины POS, включая скидки в корзине, позиции и клиентов. Этот API включает в себя множество функций для добавления и удаления содержимого корзины, а также объект, на который можно подписаться, который позволяет расширению пользовательского интерфейса получать обновления корзины.</em></p> <h3 id="добавление-товара" data-svelte-h="svelte-747220"><a class="heading-link" title="Permalink" aria-hidden="true" href="#добавление-товара"><span>#</span></a>Добавление товара</h3> <p data-svelte-h="svelte-mulheb">Чтобы добавить в корзину несколько товаров, вам необходимо отправить в <code>Cart API</code> объект <code>items</code> с идентификатором(id) продукта и количеством(quantities) товара. На скриншоте ниже я добавляю один товар по клику.</p> <p data-svelte-h="svelte-1xpm0i9"><img src="https://leonardo.osnova.io/045905e3-5c17-55bb-9b3d-306e203d8f5a/-/preview/600/-/format/webp/" alt="Пример отправляемого объекта"></p> <div class="callout-block info svelte-sxx0n0"><div class="icon-wrapper svelte-sxx0n0"><svg width="100%" height="100%" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 11.5V16.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 7.51L12.01 7.49889" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></div> Обязательно отправляйте идентификатор продукта вместо идентификатора варианта, если у вашего продукта есть варианты, иначе будет ошибка.</div> <h3 id="отправляемый-объект" data-svelte-h="svelte-3cisbt"><a class="heading-link" title="Permalink" aria-hidden="true" href="#отправляемый-объект"><span>#</span></a>Отправляемый объект</h3> <p data-svelte-h="svelte-1ivc20y">Так должен выглядеть отправляемый объект:</p> <pre class="language-json"><!-- HTML_TAG_START --><code class="language-json">items<span class="token operator">:</span> <span class="token punctuation">[</span> 
 <span class="token punctuation">&#123;</span> 
  id<span class="token operator">:</span> <span class="token number">36110175633573</span><span class="token punctuation">,</span> 
    quantity<span class="token operator">:</span> <span class="token number">2</span> 
  <span class="token punctuation">&#125;</span> 
<span class="token punctuation">]</span></code><!-- HTML_TAG_END --></pre> <h3 id="пример-fetch-запроса" data-svelte-h="svelte-7pbez6"><a class="heading-link" title="Permalink" aria-hidden="true" href="#пример-fetch-запроса"><span>#</span></a>Пример fetch запроса</h3> <p data-svelte-h="svelte-1lmob97">Пример того, как можно сделать <code>fetch</code> запрос. Это не самая сложная версия такого запроса, но и не самая простая.</p> <div class="code-block svelte-1pkpsrg"><div class="filename svelte-1pkpsrg">script.js</div> <div class="lang svelte-1pkpsrg">js</div> <pre class="language-js"><!-- HTML_TAG_START --><code class="language-js">document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">"form.configurator-form"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">form</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
    form<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"submit"</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
      e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

      <span class="token comment">// Показываем спиннер загрузки</span>
      <span class="token keyword">const</span> loadingOverlays <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">".loading-overlay"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      loadingOverlays<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">overlay</span><span class="token punctuation">)</span> <span class="token operator">=></span> overlay<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token string">"hidden"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

      <span class="token comment">// Собираем данные товаров</span>
      <span class="token keyword">const</span> productData <span class="token operator">=</span> selectedProducts<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">product</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
        <span class="token literal-property property">id</span><span class="token operator">:</span> product<span class="token punctuation">.</span>id<span class="token punctuation">,</span>
        <span class="token literal-property property">quantity</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
        <span class="token literal-property property">variantId</span><span class="token operator">:</span>
          product<span class="token punctuation">.</span>variantId <span class="token operator">&amp;&amp;</span> product<span class="token punctuation">.</span>variantId <span class="token operator">!==</span> product<span class="token punctuation">.</span>id
            <span class="token operator">?</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>product<span class="token punctuation">.</span>variantId<span class="token punctuation">)</span>
            <span class="token operator">:</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span>
      <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

      <span class="token keyword">const</span> requestBody <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
        <span class="token literal-property property">items</span><span class="token operator">:</span> productData<span class="token punctuation">,</span>
      <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>

      <span class="token comment">// Добавляем товары в корзину</span>
      <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">&#96;</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>window<span class="token punctuation">.</span>Shopify<span class="token punctuation">.</span>routes<span class="token punctuation">.</span>root<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">cart/add.js</span><span class="token template-punctuation string">&#96;</span></span><span class="token punctuation">,</span> <span class="token punctuation">&#123;</span>
        <span class="token literal-property property">method</span><span class="token operator">:</span> <span class="token string">"POST"</span><span class="token punctuation">,</span>
        <span class="token literal-property property">headers</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span>
          <span class="token string-property property">"Content-Type"</span><span class="token operator">:</span> <span class="token string">"application/json"</span><span class="token punctuation">,</span>
        <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
        <span class="token literal-property property">body</span><span class="token operator">:</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>requestBody<span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

      <span class="token comment">// Обновляем корзину</span>
      <span class="token keyword">const</span> res <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/cart.json"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">const</span> cart <span class="token operator">=</span> <span class="token keyword">await</span> res<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

      <span class="token comment">// Обновляем число на корзине</span>
      document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">".cart-count-bubble"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
        el<span class="token punctuation">.</span>textContent <span class="token operator">=</span> cart<span class="token punctuation">.</span>item_count<span class="token punctuation">;</span>
      <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

      <span class="token comment">// Перенаправляем пользователя на страницу корзины</span>
      window<span class="token punctuation">.</span>location<span class="token punctuation">.</span>href <span class="token operator">=</span> <span class="token string">"/cart"</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code><!-- HTML_TAG_END --></pre></div> <h2 id="заключение" data-svelte-h="svelte-lr9prh"><a class="heading-link" title="Permalink" aria-hidden="true" href="#заключение"><span>#</span></a>Заключение</h2> <p data-svelte-h="svelte-sjjqid">Будьте внимательны когда перед вами встанет эта задача, там довольно много подводных камней. Например, если у товара нет вариантов, то ID в value нужно передавать вот так:</p> <pre class="language-liquid"><!-- HTML_TAG_START --><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span> <span class="token object">product</span><span class="token punctuation">.</span>selected_or_first_available_variant<span class="token punctuation">.</span>id <span class="token delimiter punctuation">&#125;&#125;</span></span></code><!-- HTML_TAG_END --></pre> <p data-svelte-h="svelte-cghsdv">Полный код передаваемого инпута будет выглядеть так:</p> <pre class="language-html"><!-- HTML_TAG_START --><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>visually-hidden<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>radio<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>product<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>&#123;&#123;</span> <span class="token attr-name">product.selected_or_first_available_variant.id</span> <span class="token attr-name">&#125;&#125;</span><span class="token punctuation">></span></span></code><!-- HTML_TAG_END --></pre> <p data-svelte-h="svelte-1pqgtmk">Но если варианты есть, то уже так:</p> <pre class="language-liquid"><!-- HTML_TAG_START --><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span> <span class="token object">product</span><span class="token punctuation">.</span>id <span class="token delimiter punctuation">&#125;&#125;</span></span></code><!-- HTML_TAG_END --></pre> <p data-svelte-h="svelte-otdpto">Полный код похож на предыдущий input, просто value другое:</p> <pre class="language-html"><!-- HTML_TAG_START --><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>visually-hidden<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>radio<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>product<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>&#123;&#123;</span> <span class="token attr-name">product.id</span> <span class="token attr-name">&#125;&#125;"</span><span class="token punctuation">></span></span></code><!-- HTML_TAG_END --></pre> <p data-svelte-h="svelte-5os1ob">Вот такой небольшой трюк, который вы теперь знаете. И ещё теперь вы умеете добавлять в корзину несколько товаров. Хорошей разработки!</p> <h2 id="ресурсы" data-svelte-h="svelte-10ypkhk"><a class="heading-link" title="Permalink" aria-hidden="true" href="#ресурсы"><span>#</span></a>Ресурсы</h2> <ul data-svelte-h="svelte-1kw39c6"><li><a href="https://partners.shopify.com/signup" rel="nofollow">Создать партнёрский аккаунт</a>.</li> <li><a href="https://shopify.pxf.io/jWEzd0" rel="nofollow">Открыть магазин на Shopify за $1</a>.</li></ul>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/shopify-cart-api-obzor.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/shopify-cart-api-obzor.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/frontend-is-dead</guid>
          <title>Фронтенд умер или коротко о Next.js 14</title>
          <description>Next.js обновился до 14 версии и принёс новые фишки. На этот раз это Server Actions. Давайте разберёмся что это значит для индустрии фронтенда и когда можно говорить 'Я вообще-то фуллстек, а не фронтендер'.</description>
          <link>https://devmoek.ru/frontend-is-dead</link>
          <pubDate>Sun, 26 Nov 2023 21:55:15 +0000</pubDate>
          <category>frontend</category><category>react</category><category>next.js</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/frontend-is-dead">
                  читать на сайте
                </a>
              </strong>
            </div>

            <h2 id="фронтенд-умер" data-svelte-h="svelte-rv8aax"><a class="heading-link" title="Permalink" aria-hidden="true" href="#фронтенд-умер"><span>#</span></a>Фронтенд умер?</h2> <p data-svelte-h="svelte-r0e656">Для тех кто не хочет долго читать - пока что фронтенд жив, но есть нюанс.</p> <h2 id="в-чем-нюанс" data-svelte-h="svelte-jpylbv"><a class="heading-link" title="Permalink" aria-hidden="true" href="#в-чем-нюанс"><span>#</span></a>В чем нюанс?</h2> <p data-svelte-h="svelte-17noxbs">Недавно Next.js обновился на 14 версию. Самое основное, что добавили - Server Actions. Если простым языком, это когда в одном файле, да даже в одной функции может быть фронтенд и бэкенд код.</p> <pre class="language-js"><!-- HTML_TAG_START --><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">ServerComponent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">myAction</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token string">'use server'</span>
    <span class="token comment">// ...</span>
  <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code><!-- HTML_TAG_END --></pre> <p data-svelte-h="svelte-1exm3nc">Server Actions появились в версие Next.js 13.4, но тогда они были как эспериментальная функция. Я её кстати успел попробовать на одном из своих пет-проектов. Ещё в этой версие добавили App Router, что было довольно непривычно первое время, но это уже другая тема.</p> <p data-svelte-h="svelte-9xdf8q">Казалось бы, а что в этом такого? А дело в том, что при таком подходе как таковой фронтенд уже не используется. Точнее даже не так, он используется, но уже в связки с бэкендом. А это уже фулстек - когда разработчик пишет фронтенд и бэкенд.</p> <h3 id="серверный-рендеринг" data-svelte-h="svelte-1d0tvt8"><a class="heading-link" title="Permalink" aria-hidden="true" href="#серверный-рендеринг"><span>#</span></a>Серверный рендеринг</h3> <p data-svelte-h="svelte-rrvmyy">Тендеция перехода на серверные компонтенты довольно чиста и понятна. Это как минимум быстро.</p> <p data-svelte-h="svelte-1qm9dsg">Забавно то, что PHP использует серверный рендеринг с самого зарождения языка, а если грубо говорить, то это 1994 год. Конечно, в самом 1994 году были немного другие задачи, чем сейчас, но подход тот же.</p> <p data-svelte-h="svelte-789vut">А вот тут в клиентском компоненте имопртируется серверный компонент:</p> <pre class="language-javascript"><!-- HTML_TAG_START --><code class="language-javascript"><span class="token string">'use client'</span>

<span class="token keyword">import</span> <span class="token punctuation">&#123;</span> myAction <span class="token punctuation">&#125;</span> <span class="token keyword">from</span> <span class="token string">'./actions'</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">ClientComponent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token operator">&lt;</span>form action<span class="token operator">=</span><span class="token punctuation">&#123;</span>myAction<span class="token punctuation">&#125;</span><span class="token operator">></span>
      <span class="token operator">&lt;</span>button type<span class="token operator">=</span><span class="token string">"submit"</span><span class="token operator">></span>Add to Cart<span class="token operator">&lt;</span><span class="token operator">/</span>button<span class="token operator">></span>
    <span class="token operator">&lt;</span><span class="token operator">/</span>form<span class="token operator">></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code><!-- HTML_TAG_END --></pre> <h2 id="что-будет-с-фронтендом" data-svelte-h="svelte-1496ud0"><a class="heading-link" title="Permalink" aria-hidden="true" href="#что-будет-с-фронтендом"><span>#</span></a>Что будет с фронтендом?</h2> <p data-svelte-h="svelte-w737wi">Рынок фронтенда плавно двигается к фуллстэк, то есть фронтендерам нужно будет знать бэкенд, как минимум как писать SQL запросы к базе данных, какие бывают базы данных, и как шифровать данные.</p> <h2 id="заключение" data-svelte-h="svelte-lr9prh"><a class="heading-link" title="Permalink" aria-hidden="true" href="#заключение"><span>#</span></a>Заключение</h2> <p data-svelte-h="svelte-jpifzc">Как-будто сам фронтенд стал легче, но чтобы быть конкурентным на рынке к нему добавился ещё и бэкенд. Для новичков это может стать небольшой проблемой, ведь часто люди задаются вопросом: “А что учить, фронтенд или бэкенд?”. Сейчас всё двигается к тому, что фронтендеры сами по себе вымирают. А если вы фулл-стек, то нечего переживать.</p> <h2 id="ресурсы" data-svelte-h="svelte-10ypkhk"><a class="heading-link" title="Permalink" aria-hidden="true" href="#ресурсы"><span>#</span></a>Ресурсы</h2> <ul data-svelte-h="svelte-1x38qgc"><li><a href="https://nextjs.org/blog/next-14" rel="nofollow">Подробнее про Next.js 14</a>;</li> <li><a href="https://nextjs.org/blog/next-13-4" rel="nofollow">Первое появление Server Actions в Next.js</a>;</li> <li><a href="https://dashboard.myerswebagency.com/" rel="nofollow">Ссылка</a>, на случай если вам интересно, что за пет-проект я делал с использованием Server Actions.</li></ul>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/frontend-umer.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/frontend-umer.png"/>          
        </item>
      
        <item>
          <guid>https://devmoek.ru/shopify-editions-23-obzor</guid>
          <title>Shopify Editions '23 - Обзор</title>
          <description>Shopify каждые полгода выпускает крупное обновление, на этот раз мы разберём Летнюю версию обновления. Добавили как обычно очень много всего, больше 100 новвоведений. В этой статье я разберу лишь основные обновления.</description>
          <link>https://devmoek.ru/shopify-editions-23-obzor</link>
          <pubDate>Thu, 23 Nov 2023 21:55:15 +0000</pubDate>
          <category>shopify</category><category>shopify editions</category>
          <content:encoded><![CDATA[
            <div style="margin: 50px 0; font-style: italic;">
              If anything looks wrong, 
              <strong>
                <a href="https://devmoek.ru/shopify-editions-23-obzor">
                  читать на сайте
                </a>
              </strong>
            </div>

            <h2 id="статья-доступна-в-видео-формате" data-svelte-h="svelte-1orhznw"><a class="heading-link" title="Permalink" aria-hidden="true" href="#статья-доступна-в-видео-формате"><span>#</span></a>Статья доступна в видео-формате</h2> <iframe width="100%" height="400" src="https://www.youtube.com/embed/MlkQ4aIqefQ?si=twi3TEKpg-3WEB6_" title="Ютуб видео-плеер" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> <h2 id="содержание" data-svelte-h="svelte-1aprgkl"><a class="heading-link" title="Permalink" aria-hidden="true" href="#содержание"><span>#</span></a>Содержание</h2> <ul data-svelte-h="svelte-uwpa1s"><li><a href="#%D1%81%D1%82%D0%B0%D1%82%D1%8C%D1%8F-%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%BD%D0%B0-%D0%B2-%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B5">Статья доступна в видео-формате</a></li> <li><a href="#%D1%81%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5">Содержание</a></li> <li><a href="#sidekick--shopify-magic">Sidekick \&amp; Shopify Magic</a></li> <li><a href="#%D0%BD%D0%BE%D0%B2%D1%8B%D0%B9-%D0%B4%D0%B8%D0%B7%D0%B0%D0%B9%D0%BD-%D0%B0%D0%B4%D0%BC%D0%B8%D0%BD-%D0%BF%D0%B0%D0%BD%D0%B5%D0%BB%D0%B8">Новый дизайн админ-панели</a></li> <li><a href="#polaris-12">Polaris 12</a></li> <li><a href="#%D0%B3%D0%B8%D0%B1%D0%BA%D0%B8%D0%B5-%D1%81%D0%B5%D0%BA%D1%86%D0%B8%D0%B8-flex-sections">Гибкие секции (flex sections)</a></li> <li><a href="#%D0%BF%D0%BB%D0%B0%D0%B3%D0%B8%D0%BD-%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%BE%D0%BA">Плагин подписок</a></li> <li><a href="#shopify-collective">Shopify Collective</a></li> <li><a href="#%D0%BD%D0%BE%D0%B2%D0%B2%D0%BE%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B2-b2b">Новвоведения в B2B</a></li> <li><a href="#marketplace-connect">Marketplace connect</a></li> <li><a href="#mockshop">mock.shop</a></li> <li><a href="#%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BB%D0%B0%D0%B3%D0%B8%D0%BD%D0%B0-search-and-discovery">Обновление плагина Search and discovery</a></li> <li><a href="#%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BD%D0%B0-remix">Шаблон приложения на Remix</a></li> <li><a href="#%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D1%8F">Приложения-расширения</a></li> <li><a href="#%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D1%8B-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BD%D0%B0-%D0%BC%D0%B5%D1%82%D0%B0%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0%D1%85">Страницы созданные на метаобъектах</a></li> <li><a href="#%D0%B7%D0%B0%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5">Заключение</a></li> <li><a href="#%D1%80%D0%B5%D1%81%D1%83%D1%80%D1%81%D1%8B">Ресурсы</a></li></ul> <h2 id="sidekick--shopify-magic" data-svelte-h="svelte-pdrwbr"><a class="heading-link" title="Permalink" aria-hidden="true" href="#sidekick--shopify-magic"><span>#</span></a>Sidekick &amp; Shopify Magic</h2> <p data-svelte-h="svelte-1a0kccv">Искусственный интеллект, созданный для электронной коммерции. Позволяет быстро управлять магазином, например, создать скидку на все продукты и добавить их новой секцией на сайт. Также вы сможете создавать статьи, имейл рассылки, анализировать ваш магазин, и ещё много всего. Если вкратце, то это Chat GPT в Шопифай магазине.</p> <h2 id="новый-дизайн-админ-панели" data-svelte-h="svelte-19lc2h7"><a class="heading-link" title="Permalink" aria-hidden="true" href="#новый-дизайн-админ-панели"><span>#</span></a>Новый дизайн админ-панели</h2> <p data-svelte-h="svelte-1ikwxuo">Админка получила новый дизайн, но даже не только новый дизайн, а также некоторые всплывающие элементы стали открываться по-другому. Любое кардинальное изменение в дизайне всегда непривычно, поэтому нашлись люди которым не понравился текущий дизайн, но также есть те кому он понравился.</p> <h2 id="polaris-12" data-svelte-h="svelte-elpd0c"><a class="heading-link" title="Permalink" aria-hidden="true" href="#polaris-12"><span>#</span></a>Polaris 12</h2> <p data-svelte-h="svelte-1qaz37h">Вместе с новым дизайном обновился Polaris — это дизайн система админ-панели Шопифай, она используется для создания всех элементов которые вы видите в админке и она нужна чтобы создавать плагины на Шопифай.</p> <p data-svelte-h="svelte-tdfe5k">Polaris был создан для того, чтобы все плагины имели один стиль с админ-панелью и не выделялись между собой.</p> <p data-svelte-h="svelte-1641f5b">Если вы хотите прочитать все о новой версии Polaris и понять, почему дизайнеры выбрали именно это решение, держите ссылку на статью от Шопифай. В статье рассказывают, например, почему акцентный цвет выбран черный вместо зеленого как раньше, или почему иконки сделали тоньше и какие варианты были рассмотрены. В общем, статья интересная.</p> <h2 id="гибкие-секции-flex-sections" data-svelte-h="svelte-1810bzu"><a class="heading-link" title="Permalink" aria-hidden="true" href="#гибкие-секции-flex-sections"><span>#</span></a>Гибкие секции (flex sections)</h2> <p data-svelte-h="svelte-1vufnuz">Создание пользовательских макетов для вашего интернет-магазина проще, чем когда-либо, с помощью флекс секций. Shopify использует CSS Flexbox, который позволяет создавать более разнонаправленные адаптивные макеты и легко выравнивать содержимое в разделах магазина. Теперь вы можете просто перетаскивать, изменять размер, группировать и редактировать блоки для вашего магазина создавая уникальный дизайн.</p> <p data-svelte-h="svelte-1aj92yz">Фишка однозначно крутая, но не представляю сколько работы нужно проделать разработчикам чтобы их темы стали поддерживать это новвоведение, даже сам Шопифай в своих темах часто использует гриды вместо флексов.</p> <h2 id="плагин-подписок" data-svelte-h="svelte-1im6668"><a class="heading-link" title="Permalink" aria-hidden="true" href="#плагин-подписок"><span>#</span></a>Плагин подписок</h2> <p data-svelte-h="svelte-u8pnev">Шопифай представили свой плагин для создания подписок на товары. Есть шутка в Шопифай коммьюнити, что они сами из коробки не делают какие-то базовые решения по типу подписок, бандлов, кастомизации страницы чекаут, чтобы другие разработчики сделали и потом Шопифай увидел, что это пользуется спросом и сделали свое решение убив при этом другие.</p> <p data-svelte-h="svelte-1enacur">Не знаю получится ли в этом случае так, что Шопифай своим плагином убьет другие плагины подписок, но какие-то базовые потребности оно точно закроет и пошатнёт рынок плагинов.</p> <p data-svelte-h="svelte-vk0g5y">Плагин ещё не вышел, поэтому пока что невозможно сказать как он работает.</p> <h2 id="shopify-collective" data-svelte-h="svelte-1qqfne3"><a class="heading-link" title="Permalink" aria-hidden="true" href="#shopify-collective"><span>#</span></a>Shopify Collective</h2> <p data-svelte-h="svelte-1yxns72">Появилась возможность коллаборировать с другими брендами и продавать их товары в своем магазине (работает пока что только с бизнесами США). Пример Shopify Collective можно посмотреть в магазине Drake Collective — американо-канадского репера Дрейка.</p> <h2 id="новвоведения-в-b2b" data-svelte-h="svelte-12ru9cu"><a class="heading-link" title="Permalink" aria-hidden="true" href="#новвоведения-в-b2b"><span>#</span></a>Новвоведения в B2B</h2> <p data-svelte-h="svelte-3fc9e2">Об обновлениях в B2B я написал в своем телеграм канале. (Перейти в телеграм канал)[https://t.me/devmoek/427].</p> <h2 id="marketplace-connect" data-svelte-h="svelte-1a865j6"><a class="heading-link" title="Permalink" aria-hidden="true" href="#marketplace-connect"><span>#</span></a>Marketplace connect</h2> <p data-svelte-h="svelte-q3abbu">Позволяет подключить каталог продуктов Shopify к ведущим мировым торговым площадкам, таким как Amazon, Walmart и eBay. Независимо от того, где вы продаете, вы можете упростить управление списками своих торговых площадок, запасами, заказами и выполнением — прямо в Shopify. Легко устанавливайте переопределения контента и цен для конкретных площадок, а также управляйте списками в больших количествах.</p> <h2 id="mockshop" data-svelte-h="svelte-1mx14dz"><a class="heading-link" title="Permalink" aria-hidden="true" href="#mockshop"><span>#</span></a>mock.shop</h2> <p data-svelte-h="svelte-1sfnwbp">Мок шоп это ресурс который предоставляет основные GraphQL запросы, а также можно их менять и смотреть что будет в ответе. Также если вы не нашли пресозданного запроса вы можете написать свой используя исскуственный интеллект.</p> <h2 id="обновление-плагина-search-and-discovery" data-svelte-h="svelte-9zo0r2"><a class="heading-link" title="Permalink" aria-hidden="true" href="#обновление-плагина-search-and-discovery"><span>#</span></a>Обновление плагина Search and discovery</h2> <p data-svelte-h="svelte-1q8l8q1">Приложение Shopify Search &amp; Discovery теперь поддерживает переименование фильтров (например отображать «теги» как «функции») , перевод фильтров и группирование значений фильтра («аква» и «бирюзовый» вместе как «синий»). Также упростили бизнесам с большими каталогами добавление, массовое редактирование и просмотр поисковых ускорителей и рекомендаций по продукции.</p> <h2 id="шаблон-приложения-на-remix" data-svelte-h="svelte-112shnn"><a class="heading-link" title="Permalink" aria-hidden="true" href="#шаблон-приложения-на-remix"><span>#</span></a>Шаблон приложения на Remix</h2> <p data-svelte-h="svelte-1egpcr">Новый шаблон приложения позволяет разработчикам создавать динамичные приложения с помощью JavaScript.</p> <p data-svelte-h="svelte-lj5vqm">GraphQL — это функция, которую вы получаете после аутентификации. Вебхуки — это маршруты. Все быстро, и сделано на Remix.</p> <p data-svelte-h="svelte-10isjlj">Чтобы начать работу с шаблоном приложения Remix, запустите <code>npm init @shopify/app@latest</code> в интерфейсе командной строки.</p> <h2 id="приложения-расширения" data-svelte-h="svelte-1os4gx"><a class="heading-link" title="Permalink" aria-hidden="true" href="#приложения-расширения"><span>#</span></a>Приложения-расширения</h2> <p data-svelte-h="svelte-1tio0qu">Приложения-расширения — это настраиваемые приложения, в которых нет встроенных страниц. Так они полностью состоят из расширений, эти приложения могут размещаться на Shopify. Они имеют URL-адрес приложения, который заполняет Shopify, его можно изменить, если хотите создать встроенные страницы или разместить своё приложение в Shopify App Store.</p> <h2 id="страницы-созданные-на-метаобъектах" data-svelte-h="svelte-zrksw7"><a class="heading-link" title="Permalink" aria-hidden="true" href="#страницы-созданные-на-метаобъектах"><span>#</span></a>Страницы созданные на метаобъектах</h2> <p data-svelte-h="svelte-eri6lz">Появилась возможность использовать метаобъекты для создания лендингов. Например, если у вас есть программа амбассадоров, то вы можете создать веб-страницу для каждого амбассадора с биографией, ссылками в социальных сетях и изображениями. Я снимал видео о создание такой страницы, ссылка будет в описание или в правом верхнем углу.</p> <h2 id="заключение" data-svelte-h="svelte-lr9prh"><a class="heading-link" title="Permalink" aria-hidden="true" href="#заключение"><span>#</span></a>Заключение</h2> <p data-svelte-h="svelte-1hmdbf1">Обновление получилось очень большим, в этом посте я показал лишь часть. Полный список обновлений вы сможете найти по <a href="https://www.shopify.com/editions/summer2023" rel="nofollow">ссылке</a>.</p> <h2 id="ресурсы" data-svelte-h="svelte-10ypkhk"><a class="heading-link" title="Permalink" aria-hidden="true" href="#ресурсы"><span>#</span></a>Ресурсы</h2> <ul data-svelte-h="svelte-1kw39c6"><li><a href="https://partners.shopify.com/signup" rel="nofollow">Создать партнёрский аккаунт</a>.</li> <li><a href="https://shopify.pxf.io/jWEzd0" rel="nofollow">Открыть магазин на Shopify за $1</a>.</li></ul>
          ]]></content:encoded>
          <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://devmoek.ru//images/posts/shopify-summer-edition-2023-obzor.png"/>
          <media:content xmlns:media="http://search.yahoo.com/mrss/" medium="image" url="https://devmoek.ru//images/posts/shopify-summer-edition-2023-obzor.png"/>          
        </item>
      
  </channel>
</rss>