Creating a Magento 2 Theme Using Alpine.js and Tailwind CSS: A Foundation for Hyvä-like Theme Development

Discover how to create a minimalist Magento 2 theme using Alpine.js and Tailwind CSS. This step-by-step guide sets the foundation for building a Hyvä-like theme, covering essential configurations with PostCSS, Tailwind, and simple interactive components.

Creating a Magento 2 Theme Using Alpine.js and Tailwind CSS: A Foundation for Hyvä-like Theme Development

In this blog post, we’ll walk through creating a simple Magento 2 theme named Joshi/Minimalist, built using Alpine.js and Tailwind CSS. This theme will be a foundation for a Hyvä-like theme, focusing on a basic template where we display some text styled with Tailwind CSS and add simple interactivity with Alpine.js.

This theme will serve as the starting point for anyone looking to build lightweight, modern Magento themes.

Prerequisites

  • Basic knowledge of Magento 2 theming
  • Familiarity with Alpine.js and Tailwind CSS
  • Node.js and npm installed on your system

Step 1: Set Up the Theme Directory

First, let’s create the theme directory under app/design/frontend/Joshi/Minimalist.

mkdir -p app/design/frontend/Joshi1/Minimalist/{Magento_Theme/{templates,layout},web/{css,js}}

Theme Registration

Create the theme.xml file in the your theme directory to register the theme.

File: app/design/frontend/Joshi/Minimalist/theme.xml

<?xml version="1.0"?>
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
    <title>Minimalist</title>
    <parent>Magento/blank</parent> <!-- Hyvä themes typically use Blank theme as a parent -->
</theme>

Declare the Theme in registration.php

File: app/design/frontend/Joshi/Minimalist/registration.php

<?php

use \Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::THEME, 'frontend/Joshi/Minimalist', __DIR__);

Step 2: Set Up Tailwind CSS and PostCSS in the Theme

Now we’ll install and configure Tailwind CSS and PostCSS directly in the theme folder.

A. Install Tailwind CSS and PostCSS

Navigate to your theme directory and run the following commands to install Tailwind CSS, PostCSS, and Autoprefixer:

cd app/design/frontend/Joshi/Minimalist
npm init -y
npm install -D tailwindcss postcss autoprefixer

B. Create postcss.config.js

Create a postcss.config.js file in the theme folder to use PostCSS for processing Tailwind CSS.

File: app/design/frontend/Joshi/Minimalist/postcss.config.js

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};

C. Create tailwind.config.js

Next, create the tailwind.config.js file, ensuring it scans for all .phtml, .html, .css, .js, and .xml files inside the theme folder for Tailwind CSS classes.

File: app/design/frontend/Joshi/Minimalist/tailwind.config.js

module.exports = {
  content: [
    './**/*.phtml',    // Scan .phtml files for Tailwind classes
    './**/*.html',     // Scan .html files for Tailwind classes
    './web/css/**/*.css', // Scan CSS files for Tailwind classes
    './web/js/**/*.js',   // Scan JS files for dynamic Tailwind classes
    './**/*.xml',      // Scan XML files for Tailwind classes
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

D. Create the styles.css File

Create a basic Tailwind CSS file in the web/css folder and import the required Tailwind directives.

File: app/design/frontend/Joshi/Minimalist/web/css/styles.css

@tailwind base;
@tailwind components;
@tailwind utilities;

Step 3: Create a Basic Template with Tailwind and Alpine.js

Now that we have Tailwind CSS and Alpine.js ready to go, let’s create a basic template.

A. Create default.xml Layout

To include the custom Tailwind CSS and Alpine.js, create a default.xml layout file.

File: app/design/frontend/Joshi/Minimalist/Magento_Theme/layout/default.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>        
        <script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" src_type="url" defer="true"></script>
    </head>
</page>

B. Create a Basic Template File

Let’s create a basic template to display some text using Tailwind classes and interactivity with Alpine.js.

File: app/design/frontend/Joshi/Minimalist/templates/text.phtml

<div x-data="{ message: 'Hello, Tailwind and Alpine.js in Magento 2!' }" class="p-4 bg-blue-100 text-center">
    <p class="text-lg font-bold text-gray-800">
        <span x-text="message"></span>
    </p>
    <button @click="message = 'You clicked the button!'" class="mt-4 bg-blue-500 text-white px-4 py-2 rounded">
        Click Me
    </button>
</div>

This template uses Tailwind CSS for basic styling and Alpine.js to change the displayed message when the button is clicked.

C. Add Template to the Home Page

Finally, let’s render this template on the homepage by updating the layout.

File: app/design/frontend/Joshi/Minimalist/Magento_Theme/layout/cms_index_index.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <referenceContainer name="content">
        <block class="Magento\Framework\View\Element\Template" name="custom_text_block" template="Magento_Theme::text.phtml"/>
    </referenceContainer>
</page>

This will render the custom block with Tailwind classes and Alpine.js functionality on the homepage.

Step 4: Build and Deploy Tailwind CSS

Now, we need to compile the Tailwind CSS file using PostCSS. Run the following command in your theme folder:

npx tailwindcss -c ./tailwind.config.js -i ./web/css/styles.css -o ./web/css/tailwind.css --watch

This will generate the tailwind.css file in your theme folder.

Include the Compiled CSS

Finally, include the compiled tailwind.css in your theme. Update default.xml to include the newly generated file:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
    	<css src="css/tailwind.css"/>        
        <script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" src_type="url" defer="true"></script>
    </head>
</page>

Step 5: Clear Cache and Deploy

Once everything is set up, run the following commands to clear the cache and deploy static content:

php bin/magento setup:upgrade
php bin/magento setup:static-content:deploy -f
php bin/magento cache:flush

In the example above, I did not explicitly remove RequireJS and KnockoutJS. Let's update the default.xml file to ensure all unnecessary JavaScript, including RequireJS, KnockoutJS, and other default Magento JavaScript components, are removed.

Here is the updated default.xml:

Updated default.xml:

Updated Content:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <!-- Remove unnecessary JS to speed up page load -->
        <remove src="requirejs/require.js"/>
        <remove src="mage/polyfill.js"/>
        <remove src="Magento_Ui/js/core/app.js"/>
        <remove src="Magento_Customer/js/customer-data.js"/>
        <remove src="Magento_Checkout/js/view/minicart.js"/>
        <remove src="Magento_Checkout/js/proceed-to-checkout.js"/>

        <!-- Remove KnockoutJS -->
        <remove src="knockoutjs/knockout.js"/>
        <remove src="Magento_Ui/js/lib/knockout/bindings/bootstrap.js"/>
        <remove src="Magento_Ui/js/lib/knockout/bindings/mage-init.js"/>
        <remove src="Magento_Ui/js/lib/knockout/bindings/action.js"/>

        <!-- Optional: Remove other default Magento JS components as needed -->
        <remove src="mage/requirejs/mixins.js"/>
        <remove src="Magento_Ui/js/view/messages.js"/>
        <remove src="mage/validation/validation.js"/>
        
        <css src="css/tailwind.css"/>
        <script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" src_type="url" defer="true"></script>
    </head>
</page>

Explanation of Key Removals:

  1. RequireJS: requirejs/require.js and mage/polyfill.js are removed to ensure Magento's default JavaScript loading mechanism (RequireJS) is not used.
  2. KnockoutJS: All Knockout.js related files, including knockoutjs/knockout.js and related bindings, are removed since Hyvä themes do not rely on Magento’s default JavaScript binding framework.
  3. Other Magento JS Components: Several Magento components like customer-data.js, minicart.js, and app.js are removed to streamline the frontend and remove unused features, improving performance.

Steps After Update:

Clear Cache: Clear the cache to apply the changes:

php bin/magento cache:flush

Deploy Static Content: After updating the layout file, deploy static content:

php bin/magento setup:static-content:deploy -f

What This Achieves:

  • No RequireJS or KnockoutJS: The theme will no longer rely on RequireJS or KnockoutJS, aligning with the Hyvä approach, which uses modern and minimal JavaScript frameworks like Alpine.js.
  • Better Performance: By removing unnecessary JavaScript components, you reduce the overall JavaScript footprint, leading to faster page loads.
  • Custom Flexibility: The updated layout is now entirely in your control to define how the JavaScript and front-end functionalities behave using Alpine.js or pure JavaScript.

This updated version of the default.xml should prevent any require.config errors and ensure a lightweight frontend in line with the Hyvä philosophy.

Conclusion

You’ve successfully created a Magento 2 theme named Joshi/Minimalist using Tailwind CSS for styling and Alpine.js for lightweight interactivity. This theme serves as a solid foundation for building a Hyvä-like theme with a modern, minimal setup. In this post, we set up PostCSS and Tailwind CSS in the theme directory itself, allowing for isolated development within the theme.

You can now expand this foundation to include more complex components, grid layouts, and advanced functionality as you continue building your theme.