Medusa: Node.js платформа электронной коммерции для 11ty

В этом уроке вы узнаете, как создать современный магазин электронной коммерции с помощью Medusa и 11ty. Вы создадите бэкенд нашего магазина с помощью безголового коммерческого движка Medusa и панели администратора, а фронтенд магазина — с помощью фреймворка 11ty и tailwind CSS.

Medusa — это альтернатива Shopify с открытым исходным кодом, предоставляющая решение для безголовой коммерции, ориентированное на максимальную гибкость разработчиков. 11ty — это очень гибкий простой статический генератор сайтов, используемый для создания современных веб-сайтов.

В этом руководстве вы узнаете, как:

  1. Настроить внутренний сервер Medusa
  2. Установить пространство DigitalOcean для более удобного управления файлами
  3. Настроить панель администратора Medusa для более удобного управления вашим интернет-магазином
  4. Создать простую витрину с помощью 11ty и TailwindCSS.

Ниже представлено видео о том, что мы будем создавать.

Необходимые условия
Чтобы пройти этот учебник, убедитесь, что у вас установлены:

  • Nodejs и NPM установлены на вашей локальной машине. Чтобы полностью установить Nodejs и npm на локальный компьютер, следуйте инструкциям по этой ссылке.
  • Git установлен локально с учетной записью GitHub. Следуйте инструкциям здесь, чтобы установить git, и создайте учетную запись GitHub здесь.
  • Учетная запись DigitalOcean. Создайте учетную запись DigitalOcean здесь.

Почему именно Medusa?

  • Открытый исходный код — Medusa — это программное обеспечение с открытым исходным кодом, которое может быть использовано в качестве бэкенда для вашего интернет-магазина и имеет большое сообщество поддержки, доступ к которому вы можете получить здесь.
  • Безголовая архитектура — Безголовая архитектура Medusa позволяет легко создать любой тип фронтенда (например, 11ty) и интегрировать его с вашими любимыми CMS, решениями для оплаты, выполнения заказов и т.д.
  • Поддержка нескольких рынков — Medusa изначально поддерживает несколько валют и позволяет использовать локальных поставщиков услуг доставки и оплаты для глобальной настройки.
  • Полная настраиваемость — Наша расширяемая архитектура позволяет легко настроить Medusa для любого типа расширенного сценария использования и упрощает встраивание пользовательской логики и интеграций.

Установка и настройка бэкенда Medusa

Первым шагом в этом руководстве будет установка сервера Medusa и панели администратора. Medusa предоставляет 3 основных компонента для управления вашими коммерческими проектами — безголовый коммерческий движок, который предоставляет REST API для вашего внешнего интерфейса, настраиваемый внешний интерфейс и панель администратора для управления вашим магазином.

В этом проекте мы будем использовать только безголовый торговый движок и панель администратора, поскольку мы будем создавать витрину магазина на 11ty. Чтобы настроить внутренний сервер, сначала установите Medusa CLI.

npm install -g @medusajs/medusa-cli
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Затем создайте новый проект с установленным CLI.

medusa new <my-medusa-store> --seed
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Измените предпочтительное имя вашего проекта. Перейдите в созданную папку и создайте нового пользователя.

cd <my-medusa-store>
medusa user -e <some@email.com> -p <some_password>
Войдите в полноэкранный режим Выйти из полноэкранного режима

Измените <some@email.com> на предпочитаемый email и пароль.

Наконец, запустите созданный сервер.

medusa develop
Войти в полноэкранный режим Выход из полноэкранного режима

Доступ к серверу можно получить по адресу http://localhost:9000.

Настройка пространства DigitalOcean для загрузки изображений
После установки сервера Medusa следующим шагом будет настройка пространства DigitalOcean для хранения загруженных изображений. Для этого:

  • Откройте свою учетную запись DigitalOcean. Перейдите в раздел Spaces. Создайте новое пространство с настройками по умолчанию.
  • Выберите созданное пространство и нажмите Manage Keys.

  • Нажмите кнопку Generate New Key (Создать новый ключ).

  • Добавьте имя ключа и сохраните его.

Идентификатор ключа и секретный ключ будут сгенерированы автоматически, скопируйте ключи в безопасное место. Теперь вернитесь в папку проекта medusa и установите пакет medusa-file-spaces.

npm install medusa-file-spaces
Вход в полноэкранный режим Выйдите из полноэкранного режима

Затем откройте файл medusa-config.js и добавьте следующий пример кода в раздел plugins.

{
    resolve: `medusa-file-spaces`,
    options: {
        spaces_url: "https://test.fra1.digitaloceanspaces.com",
        bucket: "test",
        endpoint: "fra1.digitaloceanspaces.com",
        access_key_id: "YOUR-ACCESS-KEY",
        secret_access_key: "YOUR-SECRET-KEY",
    },
},
Вход в полноэкранный режим Выйти из полноэкранного режима

Измените spaes_url на URL созданного вами пространства DigitalOcean, измените bucket на имя пространства, измените access_key_id на ID сгенерированного ключа и измените secret_access_key на сгенерированный секретный ключ.

Настройка и установка панели администратора Medusa
Medusa предоставляет панель администратора, которая упрощает настройку и управление нашим магазином. Для установки панели администратора необходимо сначала клонировать репозиторий администратора с GitHub.

git clone https://github.com/medusajs/admin <medusa-admin>
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Измените имя папки на предпочитаемое вами. Затем перейдите в папку admin

cd <medusa-admin>
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Установите все необходимые пакеты

npm install
Войдите в полноэкранный режим Выйдите из полноэкранного режима

И, наконец, запустите панель администратора

npm start
Войти в полноэкранный режим Выйти из полноэкранного режима

Панель администратора загрузится по адресу http://localhost:7000/.

Войдите в систему, используя почту и пароль пользователя вашего сервера, чтобы получить доступ к панели администратора.

Добавление товаров в магазин
Теперь, когда мы полностью настроили сервер Medusa и панель администратора, следующим шагом будет добавление товаров в наш магазин. Мы будем делать это через панель администратора, так как панель администратора делает это намного проще, чем отправка API-запросов на сервер напрямую.

Чтобы добавить товар в магазин:

  1. Выберите продукты в боковом меню и нажмите Новый продукт в правой части окна.

  2. Добавьте информацию о продукте и нажмите Сохранить, чтобы зарегистрировать новый продукт.

  3. На следующем шаге нажмите Опубликовать, чтобы опубликовать новый продукт.

Обязательно добавьте в магазин как минимум 3 продукта, это необходимо для завершения настройки фронтенда в данном учебном пособии. Для каждого продукта обязательно добавьте:

  • уменьшенное изображение
  • 4 изображения товара
  • Название продукта
  • Описание товара
  • Ручка (ручка должна быть в формате slug, т.е. футболки, кепки для лица и т.д.).

Создание коллекций товаров
После добавления товаров в магазин, следующим шагом будет их группировка в коллекции. В данном руководстве мы будем использовать:

  • Коллекция еженедельных продаж
  • Коллекция бестселлеров

Чтобы создать коллекцию:

  1. Выберите коллекции под продуктами в боковом меню. Нажмите Новая коллекция в правом верхнем углу, чтобы создать новую коллекцию.

  2. Добавьте название и название коллекции, затем нажмите Сохранить.

Чтобы добавить продукт в коллекцию,

  1. Нажмите на продукт на странице продукта, чтобы открыть страницу информации о продукте.

  2. Нажмите на выпадающий список коллекции и выберите коллекцию, чтобы добавить продукт в эту коллекцию.

  3. Нажмите кнопку Сохранить, чтобы сохранить изменения. Обязательно добавьте каждый продукт в коллекцию.

Установка и настройка 11ty storefront

Теперь, когда наша установка Medusa завершена и продукты добавлены, следующим шагом в нашем руководстве будет создание витрины для нашего магазина с помощью 11ty frontend framework. 11ty — это простой статический генератор сайтов с нулевыми настройками по умолчанию, это гибкий фреймворк, который позволяет использовать сразу несколько языков шаблонов, таких как Nunjucks, Liquid, Javascript, markdown и др.

Чтобы установить 11ty, создайте новую папку с предпочтительным названием вашей витрины. Перейдите в папку и инициализируйте ее с помощью npm.

npm init -y
Войдите в полноэкранный режим Выйдите из полноэкранного режима

В папку будет добавлен файл package.json. Затем установите 11ty в папку с помощью следующей команды.

npm install --save-dev @11ty/eleventy
Войти в полноэкранный режим Выйти из полноэкранного режима

Подтвердите установку следующей командой.

npx @11ty/eleventy
Войти в полноэкранный режим Выйти из полноэкранного режима

В случае успешной установки вы должны получить ответ, подобный этому.

Wrote 0 files in 0.03 seconds (v0.12.1)
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь, когда мы завершили настройку 11ty, следующим шагом будет установка TailwindCSS во фронтенд. TailwindCSS — это css-фреймворк, используемый для создания современных веб-сайтов. Посетите сайт https://tailwindcss.com/, чтобы узнать больше об этом css-фреймворке.

Чтобы добавить TailwindCSS в 11ty, сначала установите TailwindCSS и его зависимости.

npm install tailwindcss postcss-cli autoprefixer
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Затем создайте конфигурационный файл tailwind с помощью следующей команды.

npx tailwind init
Войти в полноэкранный режим Выйти из полноэкранного режима

Создайте новый файл с именем postcss.config.js и добавьте в него следующее.

// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Создайте папку css и добавьте в нее файл index.css. Затем добавьте следующий фрагмент кода в файл c*ss/index.css*.

@tailwind base;
@tailwind components;
@tailwind utilities;
Вход в полноэкранный режим Выход из полноэкранного режима

Наконец, обновите файл package.json следующим фрагментом кода.

 "scripts": {
   "dev": "postcss css/index.css -o _site/css/index.css && eleventy --serve --quiet",
   "build": "postcss css/index.css -o _site/css/index.css"
 },
Войти в полноэкранный режим Выход из полноэкранного режима

Чтобы запустить сервер 11ty, выполните команду npm run dev. Сервер откроется по адресу http://localhost:8080/.

Создайте файловую структуру витрины магазина
11ty — это очень гибкий фреймворк, который поставляется с нулевыми настройками. Мы сами можем настроить наш проект так, как захотим. Добавьте папку src в корневую папку, это основная папка, в которой будут храниться наши файлы. Также добавьте папки _includes и _helper в папку src. Файлы компонентов будут храниться в папке src/_includes, а файлы данных будут храниться в папке src/_helpers.

Добавьте файл .eleventy.js в корневую папку и добавьте в .eleventy.js следующие фрагменты кода.

const HtmlMin = require('html-minifier');
const ErrorOverlay = require('eleventy-plugin-error-overlay');
 module.exports = eleventyConfig => {
 eleventyConfig.setTemplateFormats(['md']);
 eleventyConfig.addPlugin(ErrorOverlay);
 eleventyConfig.addTransform('htmlmin', (content, outputPath) => {
   if (outputPath.endsWith('.html')) {
     const minified = HtmlMin.minify(content, {
       useShortDoctype: true,
       removeComments: true,
       collapseWhitespace: true,
     });
     return minified;
   }
   return content;
 });
 return {
   dir: {
   input: "src",
   output: "_site",
   includes: "_includes",
   data: "_helpers",
   },
   jsDataFileSuffix: '.data',
 };
};
Вход в полноэкранный режим Выход из полноэкранного режима

Файл .eleventy.js — это наш основной файл конфигурации 11ty. Пример кода просто уведомляет 11ty о том, где хранятся наши файлы данных и включаемые файлы, а также где хранить выходные данные. Мы также добавили в проект плагин html-minifier и eleventy-plugin-error-overlay.

Наконец, установите эти два плагина с помощью следующей команды.

npm install html-minifier eleventy-plugin-error-overlay
Войти в полноэкранный режим Выйти из полноэкранного режима

После завершения установки структура файлов должна выглядеть следующим образом:

Создание макета витрины магазина
Следующий шаг — создание макета витрины. Мы будем в основном использовать Nunjucks в качестве шаблонизатора.

Сначала добавьте файл header.njk и файл footer.njk в папку _includes. Добавьте следующие примеры кода в файл _includes/header.njk,

<header class="bg-white text-gray-900 body-font shadow w-full">
  <div
    class="
      container
      mx-auto
      flex flex-wrap
      p-5
      flex-col
      md:flex-row
      items-center
    "
  >
    <nav class="flex flex-wrap items-center text-base md:ml-auto">
      <a
        href="/"
        class="
          mr-5
          hover:text-gray-900
          cursor-pointer
          border-b border-transparent
          hover:border-blue-600
        "
        >Products</a
      >
      <svg
        class="h-5 w-5"
        viewBox="0 0 24 24"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
      >
        <path
          d="M3 3H5L5.4 5M7 13H17L21 5H5.4M7 13L5.4 5M7 13L4.70711 15.2929C4.07714 15.9229 4.52331 17 5.41421 17H17M17 17C15.8954 17 15 17.8954 15 19C15 20.1046 15.8954 21 17 21C18.1046 21 19 20.1046 19 19C19 17.8954 18.1046 17 17 17ZM9 19C9 20.1046 8.10457 21 7 21C5.89543 21 5 20.1046 5 19C5 17.8954 5.89543 17 7 17C8.10457 17 9 17.8954 9 19Z"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
        />
      </svg>
    </nav>
    <a
      href="/"
      class="
        flex
        order-first
        lg:order-first lg:w-2/5
        title-font
        font-medium
        items-center
        lg:items-center
        mb-4
        md:mb-0
      "
    >
      <svg
        width="38"
        height="40"
        viewBox="0 0 38 40"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
      >
        <path
          d="M32.4865 6.48972L23.4254 1.28128C20.4607 -0.427092 16.8279 -0.427092 13.8631 1.28128L4.76024 6.48972C1.83728 8.19809 0 11.3648 0 14.7399V25.1984C0 28.6152 1.83728 31.7402 4.76024 33.4486L13.8214 38.6987C16.7861 40.4071 20.4189 40.4071 23.3836 38.6987L32.4448 33.4486C35.4095 31.7402 37.205 28.6152 37.205 25.1984V14.7399C37.2885 11.3648 35.4512 8.19809 32.4865 6.48972ZM18.6234 29.2819C13.4873 29.2819 9.31169 25.1151 9.31169 19.99C9.31169 14.8649 13.4873 10.6981 18.6234 10.6981C23.7594 10.6981 27.9768 14.8649 27.9768 19.99C27.9768 25.1151 23.8012 29.2819 18.6234 29.2819Z"
          fill="#56FBB1"
        /></svg>
    </a>
  </div>
</header>
Вход в полноэкранный режим Выход из полноэкранного режима

Затем добавьте следующее в файл _includes/footer.njk.

<footer class="bg-white h-30 flex items-end text-grey-900 pt-10 sm:mt-10 pt-10">
  <div
    class="
      w-full
      mx-auto
      text-gray-800
      flex flex-wrap
      justify-between
      inset-x-0
      bottom-0
      p-5
    "
  >
    <div>
      <a
        href="/"
        class="
          mr-5
          text-sm
          hover:text-gray-900
          cursor-pointer
          border-b border-transparent
          hover:border-blue-600
        "
        >Create Return</a
      >
      <a
        href="/"
        class="
          mr-5
          text-sm
          hover:text-gray-900
          cursor-pointer
          border-b border-transparent
          hover:border-blue-600
        "
        >FAQ</a
      >
      <a
        href="/"
        class="
          mr-5
          text-sm
          hover:text-gray-900
          cursor-pointer
          border-b border-transparent
          hover:border-blue-600
        "
        >Terms and Shipping</a
      >
    </div>
    <div>
      <a
        href="/"
        class="
          mr-5
          text-sm
          hover:text-gray-900
          cursor-pointer
          border-b border-transparent
          hover:border-blue-600
        "
        >Discord</a
      >
      <a
        href="/"
        class="
          mr-5
          hover:text-gray-900
          cursor-pointer
          border-b border-transparent
          hover:border-blue-600
        "
        >GitHub</a
      >
      <a
        href="/"
        class="
          mr-5
          text-sm
          hover:text-gray-900
          cursor-pointer
          border-b border-transparent
          hover:border-blue-600
        "
        >LinkedIn</a
      >
    </div>
  </div>
</footer>
Войти в полноэкранный режим Выйти из полноэкранного режима

Наконец, добавьте файл layout.njk в папку _includes. Добавьте следующий пример кода в файл _includes/layout.njk.

    <html>
      <head>
        <title>medusa storefront</title>
        <link rel="stylesheet" href="css/index.css" />
      </head>
      <div>{% include "header.njk" %}</div>
      <div>
        <body>
          <div>
            {{ content | safe }}
          </div>
        </body>
      </div>
      <div>{% include "footer.njk" %}</div>
    </html>
Вход в полноэкранный режим Выход из полноэкранного режима

В этом коде мы в основном импортируем нашу таблицу стилей css, а также обернули содержимое страницы с помощью созданных файлов header.njk и footer.njk. Чтобы использовать макет на странице, просто добавьте файл layout.njk во frontmatter страницы.

Импорт содержимого сервера Medusa в витрину магазина
Теперь, когда мы создали макет нашего магазина, следующим шагом будет импорт продуктов с сервера Medusa на витрину. Для этого нам нужно импортировать данные о товарах в качестве глобальной переменной данных 11ty.
Добавьте файл с именем products.js в папку _helpers и добавьте следующие примеры кода в файл _helper/products.js.

const { default: axios } = require('axios');
 module.exports = async () => {
 try {
   const res = await axios.get('http://localhost:9000/store/products');
   return res.data.products;
 } catch (error) {
   console.error(error);
 }
};
Вход в полноэкранный режим Выход из полноэкранного режима

Этот код выполняет запрос get к серверу Medusa и возвращает ответ, который будет сохранен как глобальные данные 11ty. Перейдите по этой ссылке, чтобы получить доступ к списку конечных точек API, предоставляемых Medusa.
Возвращенные данные могут быть доступны в любом месте витрины. Наконец, установите axios, поскольку мы будем выполнять наши вызовы api с помощью axios.

npm install axios
Вход в полноэкранный режим Выход из полноэкранного режима

Создание домашней страницы витрины
Домашняя страница витрины будет состоять из двух разделов, раздела героя и раздела товаров для отображения нашей продукции.
Добавьте файл hero.njk и файл product.njk в папку _includes. Затем добавьте следующий пример кода в файл _includes/hero.njk.

    <div class="w-full mb-10">
      <div class="flex bg-white" style="height: 600px">
        <div
          class="hidden lg:block lg:w-1/2"
          style="clip-path: polygon(10% 0, 100% 0%, 100% 100%, 0 100%)"
        >
          <img
            class=""
            src="https://user-images.githubusercontent.com/59125401/144878845-da9d252a-abfb-4fa1-8fca-fa46c7b103b1.png"
            alt="hero photo"
          />
        </div>
        <div
          class="flex items-center text-center lg:text-left px-8 md:px-12 lg:w-1/2"
        >
          <div>
            <h2 class="text-5xl font-semibold text-gray-800 md:text-4xl">
              Get Free <span class="text-indigo-600">Merch</span>
            </h2>
            <p class="mt-2 text-2xl w-3/4 text-gray-500 md:text-base">
              Contribute to Medusa and get free merch as a token of our appreciation.
            </p>
            <div class="flex justify-center lg:justify-start mt-6">
              <a
                class="
                  px-4
                  py-3
                  bg-indigo-600
                  text-gray-200 text-xs
                  font-semibold
                  rounded
                  hover:text-indigo-600
                "
                href="#"
                >Get Started</a
              >
            </div>
          </div>
        </div>
      </div>
    </div>
Вход в полноэкранный режим Выход из полноэкранного режима

Добавьте следующий пример кода в файл _includes/product.njk.

    <div  class="
        grid grid-cols-1
        gap-y-10
        sm:grid-cols-2
        gap-x-6
        lg:grid-cols-3
        max-w-6xl
        mx-auto
      "
    >
    {%- for product in products -%}
      <a  key="{{ product.id }}"
              href="/{{ product.handle }}.html"
              class="group">
        <img
          src="{{ product.thumbnail }}"
          alt="{{ product.id }}"
          class="
            w-5/6
            h-60
            rounded-md
            border
            border-gray-500
            object-center object-cover
            group-hover:opacity-75
          "
        />
        <h3 class="w-1/2 mx-auto text-indigo-600">{{ product.title }}</h3>
        <h3 class="w-1/2 mx-auto text-gray-500">${{ product.variants.0.prices.0.amount }}</h3>
      </a>
    {%- endfor -%}
    </div>
Вход в полноэкранный режим Выйти из полноэкранного режима

В этом коде мы, по сути, отобразили часть информации о нашем продукте, используя жидкий шаблонизатор. Добавьте файл index.md в папку src и добавьте следующий фрагмент кода в файл **src/index.md**.

    ---
    title: "Home"
    layout: layout.njk
    ---
    {% include hero.njk %}   
    {% include product.njk %}
Вход в полноэкранный режим Выйти из полноэкранного режима

В этом коде мы в основном импортировали файл hero.liquid и файл product.liquid с помощью переменной include. Мы также реализовали созданный нами макет, добавив его в файл в качестве лицевой части. Когда вы посетите сайт http://localhost:8080/, вы должны увидеть страницу, похожую на эту:

Создание представления одиночного продукта
Последним шагом будет создание представлений отдельных товаров, 11ty предоставляет переменную пагинации, которая позволяет нам создавать несколько файлов из одного шаблона. Создайте новый файл в папке src с именем product.md. Добавьте следующие примеры кода в файл src/product.md.


    ---
    layout: layout.njk
    pagination:
      data: products
      size: 1
      alias: product
    permalink: "/{{ product.handle }}.html"
    title: { { product.title } }
    ---

    <div
      class="
        mt-6
        max-w-2xl
        mx-auto
        sm:px-6
        lg:max-w-7xl lg:px-8 lg:grid lg:grid-cols-3 lg:gap-x-8
      "
    >
      <div class="hidden aspect-w-3 aspect-h-4 rounded-lg overflow-hidden lg:block">
        <img
          src="{{ product.thumbnail }}"
          alt="{{ product.id }}"
          class="w-full h-full object-center object-cover"
        />
      </div>
      <div class="hidden lg:grid lg:grid-cols-1 lg:gap-y-8">
        <div class="aspect-w-3 aspect-h-2 rounded-lg overflow-hidden">
          <img
            src="{{ product.images.0.url }}"
            alt="{{ product.id }}"
            class="w-full h-96 object-center object-cover"
          />
        </div>
        <div class="aspect-w-3 aspect-h-2 rounded-lg overflow-hidden">
          <img
            src="{{ product.images.1.url }}"
            alt="{{ product.id }}"
            class="w-full h-full object-center object-cover"
          />
        </div>
      </div>
      <div class="hidden lg:grid lg:grid-cols-1 lg:gap-y-8">
        <div
          class="
            aspect-w-4 aspect-h-2
            sm:rounded-lg sm:overflow-hidden
            lg:aspect-w-3 lg:aspect-h-4
          "
        >
          <img
            src="{{ product.images.2.url }}"
            alt="{{ product.id }}"
            class="w-full h-full object-center object-cover"
          />
        </div>
        <div
          class="
            aspect-w-4 aspect-h-2
            sm:rounded-lg sm:overflow-hidden
            lg:aspect-w-3 lg:aspect-h-4
          "
        >
          <img
            src="{{ product.images.3.url }}"
            class="w-full h-full object-center object-cover"
          />
        </div>
      </div>
    </div>
    <div
      class="
        max-w-2xl
        mx-auto
        pt-10
        pb-16
        px-4
        sm:px-6
        lg:max-w-4xl
        lg:pt-16
        lg:pb-24
        lg:px-8
      "
    >
      <div
        class="mt-4 space-y-3 lg:mt-0"
      >
        <h1
          class="
            flex
            justify-center
            mb-5
            text-2xl
            font-extrabold
            tracking-tight
            text-gray-900
            sm:text-3xl
          "
        >
          {{ product.title }}
        </h1>
        <div class="space-y-6">
          <p class="flex justify-center text-gray-900">{{ product.description }}</p>
          <div class="flex justify-center">
            <p class="text-sm font-bold text-gray-900">Product collection -</p>
            <p class="text-sm font-bold text-indigo-700">{{ product.collection.title }}</p>
          </div>
          <div class="flex justify-center">
            <p class="text-sm font-bold text-gray-900">Price -</p>
            <p class="text-sm font-bold text-indigo-700">${{ product.variants.0.prices.0.amount }}</p>
          </div>
         </div>
        <form>
          <div class="flex justify-center space-x-3 mb-5">
            <h1 class=" flex justify-center text-lg font-bold tracking-tight text-gray-900">Quantity -</h1>
            <input type="number" name="quantity" value="1" min="0" max="10" class="flex border-2 rounded-md text-blue-900 px-1 py-1 border-indigo-700" />
          </div>
          <h1 class=" flex justify-center mb-5 text-lg font-bold tracking-tight text-gray-900">Variants</h1>
          <div class="flex mt-2 max-w-xl mx-auto">
          {%- for variant in product.variants -%}
            <label for="{{ variant.id }}">
              {{ variant.title }}
              <span></span>
            </label>
            <input id="{{ variant.id }}" name="{{ variantId }}" type="radio" value="{{ variant.id }}" class="flex border -ml-24 mt-2 text-blue-900 border-indigo-700 w-full">
          {%- endfor -%}
          </div>
          <button
            type="submit"
            class="
              mt-10
              w-full
              bg-blue-900
              border border-transparent
              rounded-md
              py-3
              px-8
              flex
              items-center
              justify-center
              text-base
              font-medium
              text-white
              hover:bg-indigo-700
              focus:outline-none
              focus:ring-2
              focus:ring-offset-2
              focus:ring-indigo-500
            "
          >
            Add to cart
          </button>
        </form>
      </div>
    </div>
Вход в полноэкранный режим Выход из полноэкранного режима

В этом коде мы просто итерируем данные о продукте и создаем страницу с каждым продуктом. Ссылка на продукт также генерируется с помощью переменной permalink. Чтобы перейти на страницу продукта, просто щелкните на продукт на вашей домашней странице, вы должны увидеть страницу, похожую на эту:

Заключение

В этом руководстве мы создали витрину магазина с помощью Medusa и 11ty. Вы можете получить доступ к коду этого проекта в этом репозитории GitHub — https://github.com/Quadrisheriff/medusa-storefront.

Для получения дополнительной информации о Medusa, пожалуйста, посетите документацию или оставайтесь в курсе событий на Discord, где сообщество готово оказать вам поддержку.

Для получения информации о 11ty, пожалуйста, посетите их веб-страницу или получите помощь в Discord.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *