<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Abhijeet Dave - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Abhijeet Dave - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 10 May 2026 10:46:24 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/Abhidave/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Create and Use Checkboxes in Figma ]]>
                </title>
                <description>
                    <![CDATA[ Checkboxes are a fundamental part of modern UI design. They allow users to make multiple selections, confirm actions, and control features with ease. And while they may appear simple, designing intera ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-and-use-checkboxes-in-figma/</link>
                <guid isPermaLink="false">69c6a8f79aa3928a58bf4237</guid>
                
                    <category>
                        <![CDATA[ figma ]]>
                    </category>
                
                    <category>
                        <![CDATA[ checkbox ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abhijeet Dave ]]>
                </dc:creator>
                <pubDate>Fri, 27 Mar 2026 15:57:43 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/895586d9-6b46-4974-858b-2caebdf8c9f1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Checkboxes are a fundamental part of modern UI design. They allow users to make multiple selections, confirm actions, and control features with ease.</p>
<p>And while they may appear simple, designing interactive and scalable checkboxes in Figma requires a clear understanding of components, variants, states, and properties.</p>
<p>This guide walks you through everything you need to know, from the purpose and variations of checkboxes to step-by-step instructions for building fully interactive components.</p>
<p>You’ll also learn best practices to improve usability and discover ways to speed up your workflow with ready-made components, helping you create more efficient and production-ready designs.</p>
<h2 id="heading-table-of-contents">Table of Contents:</h2>
<ol>
<li><p><a href="#heading-what-is-a-checkbox">What Is a Checkbox?</a></p>
</li>
<li><p><a href="#heading-checkbox-variations-in-ui-design">Checkbox Variations in UI Design</a></p>
</li>
<li><p><a href="#heading-states-of-a-checkbox">States of a Checkbox</a></p>
</li>
<li><p><a href="#heading-steps-to-create-an-interactive-checkbox-in-figma">Steps to Create an Interactive Checkbox in Figma</a></p>
</li>
<li><p><a href="#heading-checkbox-various-properties">Checkbox: Various properties</a></p>
</li>
<li><p><a href="#heading-best-practices-for-checkboxdesign-in-figma">Best Practices for CheckboxDesign in Figma</a></p>
</li>
<li><p><a href="#heading-speed-up-with-ready-made-checkbox-components">Speed Up with Ready-Made Checkbox Components</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-what-is-a-checkbox">What Is a Checkbox?</h2>
<p>A checkbox is a user interface element that allows users to select one or more options from a set of choices. Each checkbox operates independently, allowing multiple selections at the same time.</p>
<p>In Figma, checkboxes are typically created as components with variants, allowing designers to represent different states, such as checked, unchecked, hover, or disabled, in prototypes.</p>
<h3 id="heading-what-is-the-purpose-of-a-checkbox-why-we-use-it">What Is the Purpose of a Checkbox? (Why We Use It)</h3>
<p>You can use checkboxes in your designs when users need to:</p>
<ul>
<li><p>Select multiple options</p>
</li>
<li><p>Confirm an action</p>
</li>
<li><p>Enable or disable a feature</p>
</li>
<li><p>Agree to terms or policies</p>
</li>
</ul>
<h3 id="heading-common-real-world-examples">Common real-world examples:</h3>
<ul>
<li><p>“I agree to the Terms &amp; Conditions.”</p>
</li>
<li><p>Choosing notification preferences</p>
</li>
<li><p>Selecting filters in e-commerce apps</p>
</li>
<li><p>Marking tasks as completed in to-do apps</p>
</li>
</ul>
<p>In Figma prototypes, interactive checkboxes help simulate real user behavior, making designs easier to validate before development.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770892845865/d6e00d87-1e44-4b3c-a6ad-92f02f17a9c0.png" alt="figma prototype example" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-checkbox-variations-in-ui-design">Checkbox Variations in UI Design</h2>
<h3 id="heading-different-checkbox-formats">Different Checkbox Formats</h3>
<p>Depending on your design system, checkboxes can appear in many formats:</p>
<p><strong>Card-Based Checkbox Selection</strong> – Uses cards as selectable elements with integrated checkboxes. This pattern improves visual clarity and is ideal for selecting rich content options.</p>
<p><strong>Simple To-Do List Checkboxes</strong> – Basic checkbox layout for task lists where users can mark items as complete. Commonly used for straightforward tracking and productivity flows.</p>
<p><strong>Status &amp; Completed Checkboxes</strong> – Represents different task states such as pending, in-progress, or completed. Helps users quickly understand progress and current status.</p>
<p><strong>Error State Checkboxes</strong> – Displays validation errors when a required checkbox is not selected. Often used in forms to guide users toward required actions.</p>
<p><strong>Chip-Style Checkbox Selection</strong> – Combines checkboxes with chip UI elements for compact, multi-select options. Ideal for filters, tags, or quick selections.</p>
<p><strong>Nested Checkbox Structures</strong> – Organizes checkboxes in parent-child relationships. Allows bulk selection and partial (indeterminate) states for better hierarchy control.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770893235721/92abda28-128c-47ec-a03e-cfdbc166a22e.png" alt="Checkbox Variations in UI Design" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><strong>Design tip:</strong></p>
<ul>
<li><p>Use <strong>checkboxes</strong> when users can select multiple options.</p>
</li>
<li><p>Use <strong>radio buttons</strong> when only one option is allowed.</p>
</li>
</ul>
<h2 id="heading-states-of-a-checkbox">States of a Checkbox</h2>
<p>A well-designed checkbox should clearly communicate its current state to users.</p>
<h3 id="heading-common-checkbox-states">Common Checkbox States:</h3>
<p>In the below illustration, you can see examples of the various states of checkboxes – Unchecked, Checked, Indeterminate, Disabled Uncheck, and Disabled Check:</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770893274277/15b5e3f0-f097-4830-9cb3-2ef1b020d112.png" alt="States of a Checkbox" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><strong>Unchecked (default):</strong> The default state where no selection has been made. It indicates that the option is available but not currently chosen.</p>
<p><strong>Checked:</strong> This state shows that the option has been selected by the user. It confirms an active choice and is typically represented with a checkmark.</p>
<p><strong>Hover:</strong> Appears when the user moves the cursor over the checkbox. It provides visual feedback to indicate that the element is interactive.</p>
<p><strong>Active / Pressed:</strong> Triggered when the user clicks or taps the checkbox. This state gives immediate feedback during the interaction before the final state is applied.</p>
<p><strong>Disabled:</strong> Indicates that the checkbox is not interactive and cannot be changed. It's usually dimmed to show that the option is unavailable.</p>
<p><strong>Indeterminate (partially selected):</strong> Represents a mixed or partial selection, often used in parent-child relationships. It shows that some, but not all, related options are selected.</p>
<h3 id="heading-how-figma-handles-these-states-using-variants">How Figma Handles These States (Using Variants)</h3>
<p>In Figma, these states are best managed using <strong>variants within a component</strong>, which allow you to group multiple versions of the same UI element into a single, organized component set.</p>
<p>Instead of creating separate checkbox designs for each state, variants let you define all states, like <strong>checked, unchecked, hover, and disabled</strong> inside one component. Each state becomes a <strong>variant</strong>, and you can switch between them using properties such as:</p>
<ul>
<li><p><code>State = Unchecked</code></p>
</li>
<li><p><code>State = Checked</code></p>
</li>
<li><p><code>State = Disabled</code></p>
</li>
</ul>
<p>This approach helps you maintain consistency across all checkbox instances and quickly switch states from the properties panel. It also lets you create interactive prototypes by linking variants (for example, click → change to checked), and scale design systems efficiently without duplicating components.</p>
<p>In simple terms, <strong>variants act as different “versions” of a component</strong>, and Figma allows you to connect these versions together to simulate real UI behavior – just like how a checkbox works in an actual product.</p>
<h2 id="heading-steps-to-create-an-interactive-checkbox-in-figma">Steps to Create an Interactive Checkbox in Figma</h2>
<p>Building interactive checkboxes from scratch is useful for learning. But in real projects, speed and consistency matter.</p>
<p>If you want production-ready checkbox components, check out Shadcn Studio.</p>
<p>It offers clean, scalable UI components inspired by modern design systems, helping designers move faster without sacrificing quality.</p>
<h3 id="heading-step-1-design-the-checkbox-ui">Step 1: Design the Checkbox UI</h3>
<p>Start by drawing a square (recommended size: 24 × 24 px). Then add a check icon to it for the checked state (recommended size: 20 × 20 px).</p>
<p>Next, add a text label (recommended size: 14 px medium). You can use Auto Layout for proper spacing (recommended spacing: 12).</p>
<p>It should look like this:</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770894656766/480d9c76-c6a2-4fde-a7db-47c6a5c86a3a.png" alt="Design the Checkbox UI" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h3 id="heading-step-2-create-a-component">Step 2: Create a Component</h3>
<p>Convert your checkbox design into a reusable component to ensure consistency and scalability. By adding variants, you can manage different states efficiently within a single component set.</p>
<ul>
<li><p>Select the checkbox design</p>
</li>
<li><p>Convert it into a <strong>Component</strong></p>
</li>
<li><p>Create <strong>variants</strong> for different states:</p>
<ul>
<li><p>Unchecked</p>
</li>
<li><p>Checked</p>
</li>
<li><p>Indeterminate</p>
</li>
<li><p>Disable Check</p>
</li>
<li><p>Disable Uncheck</p>
</li>
</ul>
</li>
</ul>
<p>Name the variant properties clearly, for example:</p>
<ul>
<li><p><code>State = Unchecked</code></p>
</li>
<li><p><code>State = Checked</code></p>
</li>
</ul>
<p>And so on.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770894904170/37cc0971-7e01-487f-bdc3-8392a5c1cd65.png" alt="Create a Component" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h3 id="heading-step-3-add-interactions-between-variants">Step 3: Add Interactions Between Variants</h3>
<p>Before setting up interactions, it’s important to understand what’s happening here.</p>
<p>In Figma, variants don’t automatically “know” how to switch between each other. You have to define how and when one variant transitions to another. This is done using prototype interactions.</p>
<p>Think of it like this:</p>
<ul>
<li><p>Each variant = a <strong>state</strong> (Unchecked, Checked, Hover, and so on)</p>
</li>
<li><p>Interactions = the <strong>rules</strong> that tell Figma when to switch states</p>
</li>
</ul>
<p>So when a user clicks a checkbox, you're essentially telling Figma: “When this happens (click), change from this state to that state.”</p>
<p>This is what creates the illusion of a working, interactive component, similar to how state changes work in real code.</p>
<p>Now let’s implement it:</p>
<ul>
<li><p>Switch to the <strong>Prototype</strong> tab</p>
</li>
<li><p>Select the <strong>Unchecked</strong> variant</p>
</li>
<li><p>Add an interaction:</p>
<ul>
<li><p><strong>Trigger:</strong> On click</p>
</li>
<li><p><strong>Action:</strong> Change to → Checked</p>
</li>
</ul>
</li>
</ul>
<p>Now, repeat the same steps to create the reverse interaction (so the checkbox can toggle back):</p>
<ul>
<li><p>Select the <strong>Checked</strong> variant</p>
</li>
<li><p>Add an interaction:</p>
<ul>
<li><p><strong>Trigger:</strong> On click</p>
</li>
<li><p><strong>Action:</strong> Change to → Unchecked</p>
</li>
</ul>
</li>
</ul>
<p>This two-way connection (Unchecked → Checked and Checked → Unchecked) is what creates the <strong>toggle behavior</strong> of a checkbox.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770894931100/08a7f258-04fa-4639-b96a-ff4e1a080f02.png" alt="Add Interactions Between Variants" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h3 id="heading-step-4-test-the-checkbox">Step 4: Test the Checkbox</h3>
<p>Preview the component to ensure all interactions and states are working as expected. This step helps verify that the checkbox behaves correctly before using it in your designs.</p>
<ul>
<li><p>Click Present</p>
</li>
<li><p>Interact with the checkbox</p>
</li>
<li><p>It should toggle between checked and unchecked states</p>
</li>
</ul>
<h2 id="heading-checkbox-various-properties">Checkbox: Various Properties</h2>
<p>Before diving into specific properties, let’s understand what Figma variables are and why they matter.</p>
<h3 id="heading-what-are-variables-in-figma">What Are Variables in Figma?</h3>
<p><strong>Variables</strong> in Figma allow you to store and control values, such as visibility, text, colors, sizes, or states, and reuse them across your components. Similar to how variables behave in code.</p>
<p>Instead of manually updating every instance of a component, variables let you define a value once and control it dynamically.</p>
<p>Think of variables like:</p>
<ul>
<li><p><strong>Switches (Boolean)</strong> – Show / hide elements</p>
</li>
<li><p><strong>Options (Variants)</strong> – Change between states like checked or unchecked</p>
</li>
<li><p><strong>Scalable controls</strong> – Adjust sizes, styles, or themes across multiple components</p>
</li>
</ul>
<p>This makes your components more flexible, scalable, and easier to manage, especially in larger design systems.</p>
<h3 id="heading-why-use-variables-for-checkboxes">Why Use Variables for Checkboxes?</h3>
<p>Checkboxes often need to adapt based on context, like showing labels, changing sizes, or switching states. Variables help you manage all of this without creating separate components for every variation.</p>
<p>With variables, a single checkbox component can behave in multiple ways.</p>
<h3 id="heading-what-you-can-control-with-variables">What You Can Control with Variables</h3>
<p>With Figma variables, you can:</p>
<p><strong>Show or Hide Label</strong> – Controls whether the label is visible alongside the checkbox. Useful when space is limited or the context is already clear.</p>
<p><strong>State Variant</strong> – Defines interaction states like checked, unchecked, hover, and disabled to ensure consistent behaviour and feedback.</p>
<p><strong>Size Variant</strong> – Specifies checkbox sizes (small, medium, large) to maintain visual hierarchy across different UI contexts.</p>
<p><strong>Creating Different Variant</strong> – Combines state, size, and label visibility into structured variants for scalability and easier management in Figma.</p>
<p>First, let’s learn how to show and hide the label in a checkbox.</p>
<h3 id="heading-1-turn-it-into-a-component">1. Turn it into a component</h3>
<p>You can convert your checkbox into a reusable component so it can be used consistently across your designs. This also allows you to add properties and variants later.</p>
<ul>
<li><p>Select the entire checkbox, including the checkbox icon and the label text</p>
</li>
<li><p>Press Cmd / Ctrl + Alt + K to convert it into a Component</p>
</li>
<li><p>Rename the component to Check Box</p>
</li>
</ul>
<h3 id="heading-2-create-a-boolean-property-for-the-label">2. Create a Boolean property for the label</h3>
<p>You can use a Boolean property to control whether the label is shown or hidden. This makes the component more flexible for different use cases.</p>
<ul>
<li><p>Select the main component</p>
</li>
<li><p>In the Properties section on the right panel, click +</p>
</li>
<li><p>Choose Boolean</p>
</li>
<li><p>Name the property Label</p>
</li>
<li><p>Set the default value to True</p>
</li>
</ul>
<p>This Boolean property controls the label's visibility.</p>
<h3 id="heading-3-bind-the-boolean-to-the-label-visibility">3. Bind the Boolean to the label visibility</h3>
<p>You can associate the Boolean property with the label layer to enable dynamic visibility based on the property's value.</p>
<ul>
<li><p>Select only the label text layer</p>
</li>
<li><p>In the Appearance section of the right panel</p>
</li>
<li><p>Click the icon that is highlighted in the image with a red square</p>
</li>
<li><p>Choose Bind to property</p>
</li>
<li><p>Select the Label Boolean</p>
</li>
</ul>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770894971306/95ef0efe-8299-4ca8-9094-7b11a64bd753.png" alt="Boolean to the label visibility" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Now, we’re going to learn how to add properties for size, state, and variants.</p>
<p>We'll create all checkbox designs covering:</p>
<ul>
<li><p>States: Unchecked, Checked, Indeterminate, Disabled check, Disabled uncheck</p>
</li>
<li><p>Variants: Primary, Secondary, Info, Warning, Destructive</p>
</li>
<li><p>Sizes: Sm, Md, Lg</p>
</li>
</ul>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770895088612/a08aac1e-160a-4a4e-b6eb-171f35d6d170.png" alt="how to add properties for size, state, and variant" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Then select all checkbox designs and convert them into components by selecting Create Multiple Components (<strong>Cmd / Ctrl + Alt + K</strong>)</p>
<p>With all components selected, click <strong>Combine as variants.</strong></p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770895169444/5890e140-abdb-4de2-89cd-1c6443974853.png" alt="Grid of labeled checkbox icons in various colors and states. A dropdown menu on the right shows options like &quot;Create multiple components.&quot; Additional UI elements display selection information and a &quot;Combine as variants&quot; button." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Select the main component set and rename properties:</p>
<ul>
<li><p>Rename <strong>Property 1 to state</strong></p>
</li>
<li><p>Add a <strong>Variant</strong> property and rename it to <strong>variant</strong></p>
</li>
<li><p>Add another <strong>Variant</strong> property and rename it to size</p>
</li>
</ul>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770895197034/65ec9280-cc35-495f-be4a-1dad60001331.png" alt="checkbox component creation" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Select all unchecked checkboxes and set:</p>
<ul>
<li><strong>state = Unchecked</strong></li>
</ul>
<p>Same for all state values.</p>
<ul>
<li><p>Select all primary checkboxes and set:</p>
<ul>
<li><strong>variant = Primary</strong></li>
</ul>
</li>
</ul>
<p>Same for all Variant values.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770895305294/9faa609f-afe2-4146-9cc0-c26acf80bbf5.png" alt="Design process involving checkboxes" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Then select all medium checkboxes and set:</p>
<ul>
<li><strong>size = md</strong></li>
</ul>
<p>Same for all Size values.</p>
<p>Drag any checkbox instance onto the canvas and verify that State, Variant, and Size properties work correctly:</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770895397620/65ba3b77-8d18-432e-b6e5-0f663a8fb8d6.png" alt="size values of checkbox" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-best-practices-for-checkboxdesign-in-figma">Best Practices for CheckboxDesign in Figma</h2>
<p><strong>Always include clear and readable labels</strong> – Clear labels help users quickly understand the purpose of each checkbox and reduce confusion during interaction.</p>
<p><strong>Maintain consistent spacing using Auto Layout</strong> – Consistent spacing ensures visual balance and alignment while keeping layouts scalable and structured.</p>
<p><strong>Ensure sufficient colour contrast for accessibility</strong> – Proper contrast improves visibility and ensures the checkbox is accessible to all users.</p>
<p><strong>Make the clickable area large enough</strong> – A larger clickable area enhances usability, especially on touch devices, and reduces misclicks.</p>
<p><strong>Keep interactions simple and predictable</strong> – Simple and predictable interactions help users easily understand behavior and build confidence while using the interface.</p>
<h2 id="heading-speed-up-with-ready-made-checkbox-components">Speed Up with Ready-Made Checkbox Components</h2>
<p>Building interactive checkboxes from scratch is useful for learning, but in real projects, speed and consistency matter.</p>
<p>If you want production-ready checkbox components, check out <a href="https://shadcnstudio.com/">Shadcn Studio</a>. It offers clean, scalable UI <a href="https://shadcnstudio.com/components">shadcn components</a> and blocks inspired by modern design systems, helping designers move faster without sacrificing quality.</p>
<h3 id="heading-why-use-shadcn-studio">Why use Shadcn Studio?</h3>
<ul>
<li><p>Save hours on repetitive UI work</p>
</li>
<li><p>Maintain consistent checkbox styles</p>
</li>
<li><p>Easy to integrate into existing design systems</p>
</li>
<li><p>Ideal for SaaS products, dashboards, and web apps</p>
</li>
</ul>
<p>You can explore <a href="https://shadcnstudio.com/docs/components/checkbox"><strong>Shadcn Checkbox</strong></a> components on Shadcn Studio. You'll also find animated checkbox components you can try out.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Checkboxes are small but essential UI elements that improve usability and help simulate real user interactions in Figma. By using components, variants, Auto Layout, and variables, designers can create scalable, accessible, and consistent checkbox systems.</p>
<p>Following best practices ensures clarity and better user experience, while ready-made component libraries can speed up workflows and maintain design consistency. Mastering interactive checkboxes ultimately helps designers prototype more effectively and deliver polished, production-ready interfaces.</p>
<p>I have prepared this article with the help of <a href="https://github.com/nirmiclevision">Nirmi Nagori</a>, a passionate Figma designer.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up a Registry in shadcn ]]>
                </title>
                <description>
                    <![CDATA[ In this guide, you’ll learn how to set up a registry in shadcn. If you’re not familiar with this tool, shadcn is a collection of reusable and accessible components you can use in your projects. You’ll learn about essential concepts such as setting up... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-up-a-registry-in-shadcn/</link>
                <guid isPermaLink="false">68ff81486f611e7895c9f9ca</guid>
                
                    <category>
                        <![CDATA[ shadcn ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shadcn ui ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abhijeet Dave ]]>
                </dc:creator>
                <pubDate>Mon, 27 Oct 2025 14:27:20 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761575215365/54597001-a10f-4a3d-a082-3eb5ac8b9a7d.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this guide, you’ll learn how to set up a registry in shadcn. If you’re not familiar with this tool, shadcn is a collection of reusable and accessible components you can use in your projects.</p>
<p>You’ll learn about essential concepts such as setting up and configuring the registry, adding authentication, CLI commands you can use, and more.</p>
<h2 id="heading-table-of-contents">Table of Contents:</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-a-registry-in-shadcn">What is a Registry in shadcn?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-and-configure-your-registry">How to Create and Configure Your Registry</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-namespace-system">Namespace System</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-authentication-for-private-registries">Authentication for Private Registries</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-cli-commands">CLI Commands</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-dependency-resolution">Dependency Resolution</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-error-handling">Error Handling</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-a-registry-in-shadcn"><strong>What is a registry in shadcn?</strong></h2>
<p>A <strong>registry</strong> in shadcn is a central place for sharing and managing your reusable components, utilities, and UI elements (along with other resources) across different projects. It lets developers give numbers to and organize components in a standard way. This makes it easier to integrate and share resources within and across teams.</p>
<p>The registry system helps make these components easily reusable. It also helps teams keep their code clean and manage dependencies more effectively.</p>
<p>shadcn's main system uses the <code>registry.json</code> file. The file provides key information about the registry, such as resource names and places along with the files that go with them.</p>
<h3 id="heading-why-use-a-shadcn-registry">Why use a shadcn registry?</h3>
<p>Using registries is helpful because it helps you standardize rules for your components. Every component, UI element, or utility follows a clear plan, which makes it easier to integrate and manage them.</p>
<p>Also, version numbers let you manage different versions of a component. This makes sure various parts work together and lets you update them without trouble.</p>
<p>Registries also give you the ability to organize resources into groups while managing what depends on what. Everything is flexible this way.</p>
<p>And if you create a registry, it lets you share your components with other developers (either everyone or just certain people). This allows for both inside and open-source work.</p>
<h2 id="heading-how-to-create-and-configure-your-registry">How to Create and Configure Your Registry</h2>
<p>Creating a shadcn registry involves setting up a configuration file (<code>registry.json</code>) at the root of your project. This file contains the metadata and structure of your registry, helping define components and their relationships.</p>
<p>shadcn provides this <a target="_blank" href="https://github.com/shadcn-ui/registry-template">starter template</a> to help you understand how registries work.</p>
<h3 id="heading-step-by-step-guide-to-create-a-registry">Step by Step Guide to Create a Registry</h3>
<h4 id="heading-1-define-the-registrys-metadata">1. Define the Registry's Metadata</h4>
<p>You’ll need to fill in the following information:</p>
<ul>
<li><p><code>name</code>: A unique name for the registry.</p>
</li>
<li><p><code>homepage</code>: A URL pointing to the homepage for the registry.</p>
</li>
<li><p><code>items</code>: An array that contains all available components, UI elements, or utilities in the registry.</p>
</li>
</ul>
<p>Here’s an example of a simple <code>registry.json</code>:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"$schema"</span>: <span class="hljs-string">"&lt;https://ui.shadcn.com/schema/registry.json&gt;"</span>,
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"acme"</span>,
  <span class="hljs-attr">"homepage"</span>: <span class="hljs-string">"&lt;https://acme.com&gt;"</span>,
  <span class="hljs-attr">"items"</span>: [
    <span class="hljs-comment">// Components will go here</span>
  ]
}
</code></pre>
<h4 id="heading-2-components-structure">2. Components Structure</h4>
<p>Each item in the registry can be a component, theme, hook, or utility. These items have the following properties:</p>
<ul>
<li><p><code>name</code>: Unique name of the component.</p>
</li>
<li><p><code>type</code>: Specifies the type of item (for example, <code>registry:component</code>, <code>registry:block</code>).</p>
</li>
<li><p><code>files</code>: An array of files that make up the component.</p>
</li>
</ul>
<p>Here’s an example:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"name"</span>,
  <span class="hljs-attr">"type"</span>: <span class="hljs-string">"registry:block"</span>,
  <span class="hljs-attr">"title"</span>: <span class="hljs-string">"title"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Simple description"</span>,
  <span class="hljs-attr">"files"</span>: [
    {
      <span class="hljs-attr">"path"</span>: <span class="hljs-string">"registry/new-york/..."</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"registry:component"</span>
    }
  ]
}
</code></pre>
<p>This component contains a simple button. You can keep adding more components to the <code>items</code> array.</p>
<h4 id="heading-3-adding-components">3. Adding Components</h4>
<p>After creating the <code>registry.json</code> file, you can add components to the registry. These components can be UI elements, functions, or utilities.</p>
<p><strong>Example 1: Adding a Simple Button Component</strong></p>
<p>First, create the component file. You can define your component in a separate directory. For example, we will create a <code>HelloWorld</code> component.</p>
<pre><code class="lang-json"><span class="hljs-comment">// registry/new-york/hello-world/hello-world.tsx</span>
import { Button } from <span class="hljs-string">"@/components/ui/button"</span>

export function HelloWorld() {
  return &lt;Button&gt;Hello World&lt;/Button&gt;
}
</code></pre>
<p>Reference the component in your <code>registry.json</code> like this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"hello-world"</span>,
  <span class="hljs-attr">"type"</span>: <span class="hljs-string">"registry:block"</span>,
  <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Hello World"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"A simple hello world component."</span>,
  <span class="hljs-attr">"files"</span>: [
    {
      <span class="hljs-attr">"path"</span>: <span class="hljs-string">"registry/new-york/hello-world/hello-world.tsx"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"registry:component"</span>
    }
  ]
}
</code></pre>
<p>The <code>"files"</code> key points to the path where the component is stored, while the <code>type</code> helps categorize the item.</p>
<p><strong>Example 2: Adding Multiple Components</strong></p>
<p>You can add multiple components to the registry as well. For instance, a button and a form could be part of a UI package:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"ui-kit"</span>,
  <span class="hljs-attr">"type"</span>: <span class="hljs-string">"registry:block"</span>,
  <span class="hljs-attr">"title"</span>: <span class="hljs-string">"UI Kit"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"A collection of basic UI components."</span>,
  <span class="hljs-attr">"files"</span>: [
    {
      <span class="hljs-attr">"path"</span>: <span class="hljs-string">"registry/ui-kit/button/button.tsx"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"registry:component"</span>
    },
    {
      <span class="hljs-attr">"path"</span>: <span class="hljs-string">"registry/ui-kit/form/form.tsx"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"registry:component"</span>
    }
  ]
}
</code></pre>
<p>This modular approach allows for scalable development, enabling easy additions or updates to the registry without affecting other parts of the application.</p>
<blockquote>
<p>You can learn more about <a target="_blank" href="https://ui.shadcn.com/docs/registry/getting-started">registry basics</a> in the shadcn UI docs.</p>
</blockquote>
<h2 id="heading-namespace-system"><strong>Namespace System</strong></h2>
<p>Namespaces in shadcn help arrange components, utilities, themes, or other resources. The goal is to avoid conflicts and provide a good structure for your resources.</p>
<h3 id="heading-what-is-a-namespace">What is a Namespace?</h3>
<p>A namespace groups resources under a plain identifier, usually prefixed with an '@'. With this, you can separate different types of resources, teams, or even public versus private components.</p>
<p><strong>For instance:</strong></p>
<ul>
<li><p><code>@shadcn/button</code> could represent a button component from shadcn's registry.</p>
</li>
<li><p><code>@acme/auth-utils</code> could represent authentication utilities developed by the Acme company.</p>
</li>
</ul>
<h3 id="heading-how-to-configure-multiple-registries-using-namespaces">How to Configure Multiple Registries Using Namespaces</h3>
<p>You can configure multiple registries under different namespaces, which helps organize resources by type or team:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"registries"</span>: {
    <span class="hljs-attr">"@acme-ui"</span>: <span class="hljs-string">"&lt;https://registry.acme.com/ui/{name}.json&gt;"</span>,
    <span class="hljs-attr">"@acme-docs"</span>: <span class="hljs-string">"&lt;https://registry.acme.com/docs/{name}.json&gt;"</span>,
    <span class="hljs-attr">"@acme-ai"</span>: <span class="hljs-string">"&lt;https://registry.acme.com/ai/{name}.json&gt;"</span>,
    <span class="hljs-attr">"@acme-internal"</span>: {
      <span class="hljs-attr">"url"</span>: <span class="hljs-string">"&lt;https://internal.acme.com/registry/{name}.json&gt;"</span>,
      <span class="hljs-attr">"headers"</span>: {
        <span class="hljs-attr">"Authorization"</span>: <span class="hljs-string">"Bearer ${INTERNAL_TOKEN}"</span>
      }
    }
  }
}
</code></pre>
<p>This setup allows you to:</p>
<ul>
<li><p>Keep UI components, documentation, AI resources, and internal libraries separate.</p>
</li>
<li><p>Easily manage public and private resources within the same registry configuration.</p>
</li>
</ul>
<p>You can learn more about <a target="_blank" href="https://ui.shadcn.com/docs/registry/namespace#authentication--security"><strong>Namespace</strong></a> in the shadcn UI docs.</p>
<h2 id="heading-authentication-for-private-registries">Authentication for Private Registries</h2>
<p>If you have private registries, shadcn offers several authentication methods to ensure that only authorized users can access them. These include Bearer Token (OAuth 2.0), API Key, Basic Authentication, and Query Parameter Authentication. Let’s look at each one in more detail.</p>
<h3 id="heading-bearer-token-oauth-20">Bearer Token (OAuth 2.0)</h3>
<p>Bearer tokens are ideal for integrating with external APIs like GitHub or internal services that support OAuth 2.0.</p>
<p>You include the token in the <code>Authorization</code> header of the request. You typically get this token through an OAuth 2.0 flow, and it grants access to protected resources.</p>
<p>Here’s an example:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"@github"</span>: {
    <span class="hljs-attr">"url"</span>: <span class="hljs-string">"&lt;https://api.github.com/repos/org/registry/contents/{name}.json&gt;"</span>,
    <span class="hljs-attr">"headers"</span>: {
      <span class="hljs-attr">"Authorization"</span>: <span class="hljs-string">"Bearer ${GITHUB_TOKEN}"</span>
    }
  }
}
</code></pre>
<h3 id="heading-api-key">API Key</h3>
<p>You commonly use API keys for private NPM registries or internal APIs where a simple key is sufficient for access control.</p>
<p>An API key is included in the request headers, often under <code>X-API-Key</code>. This key is issued by the service and you should keep it confidential.</p>
<p><strong>Here’s an example</strong>:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"@private"</span>: {
    <span class="hljs-attr">"url"</span>: <span class="hljs-string">"&lt;https://api.company.com/registry/{name}&gt;"</span>,
    <span class="hljs-attr">"headers"</span>: {
      <span class="hljs-attr">"X-API-Key"</span>: <span class="hljs-string">"${API_KEY}"</span>
    }
  }
}
</code></pre>
<h3 id="heading-basic-authentication">Basic Authentication</h3>
<p>You’ll typically use basic authentication in legacy systems that require basic HTTP authentication.</p>
<p>The <code>Authorization</code> header contains a base64-encoded string of the format <code>username:password</code>. While it’s pretty easy to implement, it’s less secure than more modern methods like OAuth 2.0.</p>
<p><strong>Here’s an example</strong>:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"@internal"</span>: {
    <span class="hljs-attr">"url"</span>: <span class="hljs-string">"&lt;https://registry.company.com/{name}.json&gt;"</span>,
    <span class="hljs-attr">"headers"</span>: {
      <span class="hljs-attr">"Authorization"</span>: <span class="hljs-string">"Basic ${BASE64_CREDENTIALS}"</span>
    }
  }
}
</code></pre>
<h3 id="heading-query-parameter-authentication">Query Parameter Authentication</h3>
<p>Query parameter auth is a simpler form of authentication using query parameters for APIs.</p>
<p>It works by passing authentication details as query parameters in the URL. While this is convenient, it’s less secure than other methods since query parameters can be exposed in logs or URLs.</p>
<p><strong>Here’s an example:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"@secure"</span>: {
    <span class="hljs-attr">"url"</span>: <span class="hljs-string">"&lt;https://registry.example.com/{name}.json&gt;"</span>,
    <span class="hljs-attr">"params"</span>: {
      <span class="hljs-attr">"api_key"</span>: <span class="hljs-string">"${API_KEY}"</span>,
      <span class="hljs-attr">"client_id"</span>: <span class="hljs-string">"${CLIENT_ID}"</span>,
      <span class="hljs-attr">"signature"</span>: <span class="hljs-string">"${REQUEST_SIGNATURE}"</span>
    }
  }
}
</code></pre>
<h3 id="heading-multiple-authentication-methods">Multiple Authentication Methods</h3>
<p>Some registries require multiple authentication methods simultaneously – for example, a combination of a Bearer token and an API key.</p>
<p>The request includes multiple headers and possibly query parameters to satisfy all required authentication mechanisms. This is common in enterprise environments where different layers of security are enforced.</p>
<p><strong>Here’s an example</strong>:</p>
<pre><code class="lang-bash">{
  <span class="hljs-string">"@enterprise"</span>: {
    <span class="hljs-string">"url"</span>: <span class="hljs-string">"https://api.enterprise.com/v2/registry/{name}"</span>,
    <span class="hljs-string">"headers"</span>: {
      <span class="hljs-string">"Authorization"</span>: <span class="hljs-string">"Bearer <span class="hljs-variable">${ACCESS_TOKEN}</span>"</span>,
      <span class="hljs-string">"X-API-Key"</span>: <span class="hljs-string">"<span class="hljs-variable">${API_KEY}</span>"</span>,
      <span class="hljs-string">"X-Workspace-Id"</span>: <span class="hljs-string">"<span class="hljs-variable">${WORKSPACE_ID}</span>"</span>
    },
    <span class="hljs-string">"params"</span>: {
      <span class="hljs-string">"version"</span>: <span class="hljs-string">"latest"</span>
    }
  }
}
</code></pre>
<p>You can learn more about <a target="_blank" href="https://ui.shadcn.com/docs/registry/namespace#authentication--security"><strong>Authentication and Security</strong></a> in the shadcn UI docs.</p>
<h2 id="heading-cli-commands">CLI Commands</h2>
<p>The shadcn CLI lets you interact with the registry directly from the command line. With commands like <code>add</code>, <code>view</code>, <code>search</code>, and <code>list</code>, you can easily install and manage resources. Let’s look at some examples to see how this works.</p>
<h3 id="heading-install-resources-from-the-registry">Install Resources from the Registry</h3>
<p>Use the following commands to add resources to your project:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Install a specific component</span>
npx shadcn@latest add @acme/button

<span class="hljs-comment"># Install multiple components at once</span>
npx shadcn@latest add @acme/button @lib/utils @ai/prompt
</code></pre>
<p>These commands fetch the specified components from the registry and integrate them into your project, ensuring all necessary dependencies are also installed.</p>
<h3 id="heading-viewing-metadata">Viewing Metadata</h3>
<p>Before integrating a component, it's crucial to understand its structure and dependencies. The <code>view</code> command allows you to inspect a component's metadata:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># View a specific component</span>
npx shadcn@latest view @acme/button

<span class="hljs-comment"># View multiple components</span>
npx shadcn@latest view @acme/button @lib/utils @ai/prompt

<span class="hljs-comment"># View from a URL directly</span>
npx shadcn@latest view https://registry.example.com/button.json

<span class="hljs-comment"># View from a local file</span>
npx shadcn@latest view ./local-registry/button.json
</code></pre>
<p>So what does the <code>view</code> command display?</p>
<ul>
<li><p>Resource metadata: Information such as the component's name, type, and description.</p>
</li>
<li><p>Dependencies: Lists both direct and registry dependencies required by the component.</p>
</li>
<li><p>File contents: Displays the actual code that will be installed.</p>
</li>
<li><p>CSS variables and Tailwind configuration: Shows any styling configurations associated with the component.</p>
</li>
<li><p>Required environment variables: Lists any environment variables needed for the component to function correctly.</p>
</li>
</ul>
<p>This command is invaluable for reviewing a component's details before installation, ensuring compatibility and understanding its requirements.</p>
<h3 id="heading-searching-resources"><strong>Searching Resources</strong></h3>
<p>To discover components within a registry, you can use these commands:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Search a specific registry</span>
npx shadcn@latest search @v0

<span class="hljs-comment"># Search with a query</span>
npx shadcn@latest search @acme --query <span class="hljs-string">"auth"</span>

<span class="hljs-comment"># Search multiple registries</span>
npx shadcn@latest search @v0 @acme @lib

<span class="hljs-comment"># Limit results</span>
npx shadcn@latest search @v0 --<span class="hljs-built_in">limit</span> 10 --offset 20

<span class="hljs-comment"># List all items (alias for search)</span>
npx shadcn@latest list @acme
</code></pre>
<p>They help you find components based on criteria like registry, query terms, and result limits.</p>
<p>Learn more about <a target="_blank" href="https://ui.shadcn.com/docs/registry/namespace#cli-commands"><strong>CLI Commands</strong></a> in the shadcn UI docs.</p>
<h2 id="heading-dependency-resolution">Dependency Resolution</h2>
<p>The CLI automatically resolves and installs all dependencies from their respective registries.</p>
<p>Understanding how dependencies are resolved internally is important if you're developing registries or need to customize third-party resources.</p>
<p>In shadcn, components often rely on other resources from various registries. When you install a component, shadcn ensures that all its dependencies are also installed, even if they reside in different registries. This process is known as <strong>dependency resolution</strong>.</p>
<h3 id="heading-what-does-it-mean-to-resolve-dependencies"><strong>What Does It Mean to "Resolve Dependencies"?</strong></h3>
<p>So to be clear resolving dependencies involves identifying, fetching, and installing dependencies.</p>
<p>First, shadcn determines which components a resource requires to function correctly. Then it retrieves these dependent components from their respective registries. Finally, it ensures that all dependencies are installed before the main component, maintaining the correct order.</p>
<p>This process guarantees that when you install a component, all its prerequisites are also installed, ensuring smooth functionality.</p>
<h3 id="heading-understanding-topological-sorting-in-dependency-resolution"><strong>Understanding Topological Sorting in Dependency Resolution</strong></h3>
<p><strong>Topological sorting</strong> might sound complicated, but it's essentially a method of organizing tasks (or components) in a way that makes sure everything gets done in the right order.</p>
<p>Imagine you have a list of tasks, and some tasks depend on others to be completed first. For example, you can't make a cake without first measuring out and then mixing the ingredients. So, the tasks “measure ingredients” and "mix ingredients" need to be completed before "bake the cake."</p>
<p>In the context of shadcn, topological sorting works in a similar way to organizing the installation of components:</p>
<ul>
<li><p>Each component (like <code>dashboard</code>) can depend on other components (like <code>@shadcn/card</code> or <code>@acme/data-table</code>).</p>
</li>
<li><p>Topological sorting arranges the components so that each one is installed only after the components it depends on have been installed.</p>
</li>
</ul>
<h4 id="heading-why-is-topological-sorting-important">Why Is Topological Sorting Important?</h4>
<p>Topological sorting takes care of a couple key things. First, it makes sure that components are installed in the correct order. For example, if Component A depends on Component B, then Component B will be installed first, followed by Component A.</p>
<p>It also prevents circular dependencies. If two components depend on each other, topological sorting detects this and prevents a never-ending loop (also called a circular dependency).</p>
<h4 id="heading-example-of-dependency-resolution">Example of Dependency Resolution:</h4>
<p>Consider the following component with its dependencies:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"dashboard"</span>,
  <span class="hljs-attr">"registryDependencies"</span>: [
    <span class="hljs-string">"@shadcn/card"</span>,
    <span class="hljs-string">"@v0/chart"</span>,
    <span class="hljs-string">"@acme/data-table"</span>
  ]
}
</code></pre>
<p>In this example, we have a <strong>component</strong>: <code>dashboard</code> and its <strong>dependencies</strong>: <code>@shadcn/card</code>, <code>@v0/chart</code>, and <code>@acme/data-table</code>.</p>
<p>In this case, shadcn will first identify the dependencies by recognizing that <code>dashboard</code> depends on <code>@shadcn/card</code>, <code>@v0/chart</code>, and <code>@acme/data-table</code>. Then it will fetch these components from their respective registries. Finally, it’ll install <code>@shadcn/card</code>, <code>@v0/chart</code>, and <code>@acme/data-table</code> first, before installing <code>dashboard</code>, ensuring all prerequisites are met.</p>
<p>You can learn more about <a target="_blank" href="https://ui.shadcn.com/docs/registry/namespace#authentication--security">Dependency Resolution</a> in the shadcn UI docs.</p>
<h2 id="heading-error-handling"><strong>Error Handling</strong></h2>
<p>shadcn’s CLI is equipped to handle several types of errors. Here are some common scenarios and how to resolve them:</p>
<h3 id="heading-common-errors"><strong>Common Errors</strong></h3>
<p><strong>1. Unknown Registry</strong></p>
<p>This error occurs when the registry isn’t defined in the configuration.</p>
<p>Here’s an example:</p>
<pre><code class="lang-json">Error: Unknown registry <span class="hljs-string">"@non-existent"</span>
</code></pre>
<p><strong>Solution:</strong> To fix this, just add the registry in the <code>registries</code> section of your configuration.</p>
<p><strong>2. Missing Environment Variables</strong></p>
<p>If your registry requires certain environment variables that are not set, you'll get an error.</p>
<p>Here’s an example:</p>
<pre><code class="lang-json">Registry <span class="hljs-string">"@private"</span> requires REGISTRY_TOKEN
</code></pre>
<p><strong>Solution:</strong> To fix this, just add the required environment variables to <code>.env</code> or <code>.env.local</code>.</p>
<p><strong>3. 404 Not Found</strong></p>
<p>The resource may not exist or the URL could be incorrect.</p>
<p>Here’s an example:</p>
<pre><code class="lang-json">Error: The resource was not found at &lt;https:<span class="hljs-comment">//api.company.com/button.json&gt;</span>
</code></pre>
<p><strong>4. Authentication Failures (401/403)</strong></p>
<p>If you’re not authorized to access a resource, you’ll see 401 or 403 errors.</p>
<p>To fix this, make sure your tokens, API keys, or credentials are valid.</p>
<p>You can learn more about <a target="_blank" href="https://ui.shadcn.com/docs/registry/namespace#authentication--security">Error Handling</a> in the shadcn UI docs.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The shadcn registry system provides a good, modular solution for managing and sharing components or utilities across projects. If you’re looking to explore practical implementations, platforms like <a target="_blank" href="https://shadcnstudio.com/">shadcn/studio</a> which showcase how you can leverage <a target="_blank" href="https://shadcnstudio.com/components">shadcn components</a> to build sleek, modern UI solutions with minimal setup.</p>
<p>With its structured approach to dependencies, flexible namespaces, good authentication, and CLI commands, registries enable teams to share secure resources and customize them along the way.</p>
<p>I have prepared this article with the help of <a target="_blank" href="https://github.com/PruthviPraj00">Pruthvi Prajapati</a>, a front-end developer with 3 years of experience.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Landing Page with Bootstrap 5 and Context7 MCP AI ]]>
                </title>
                <description>
                    <![CDATA[ What if you could build a responsive and stunning landing page in minutes, with little to no coding? Well, AI tools like Context7 MCP make it possible to automate design tasks and seamlessly integrate them with powerful frameworks like Bootstrap 5. I... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-a-landing-page-with-bootstrap-5-and-context7-mcp-ai/</link>
                <guid isPermaLink="false">68e413e6f01f4d585b1f9e1b</guid>
                
                    <category>
                        <![CDATA[ Bootstrap ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Bootstrap 5 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abhijeet Dave ]]>
                </dc:creator>
                <pubDate>Mon, 06 Oct 2025 19:09:26 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759776218071/dce01b69-3ae9-46da-b4a4-e9a98e42f5d1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>What if you could build a responsive and stunning landing page in minutes, with little to no coding? Well, AI tools like Context7 MCP make it possible to automate design tasks and seamlessly integrate them with powerful frameworks like Bootstrap 5.</p>
<p>In this article, you’ll learn how to effortlessly create a modern and responsive landing page using Context7 MCP and Bootstrap 5 by simply providing prompts - no expert coding required!</p>
<p>Landing pages are the cornerstone of online success. They directly influence conversion rates and play a crucial role in lead generation. But creating an effective landing page that looks great across all devices can be a daunting task. That’s where AI-powered tools can help, making it easier than ever to build a landing page that’s both visually appealing and responsive.</p>
<h2 id="heading-table-of-content">Table of Content</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-leveraging-ai-for-bootstrap-5-landing-page-code-generation">Leveraging AI for Bootstrap 5 Landing Page Code Generation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-bootstrap">What is Bootstrap?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-mcp">What is MCP?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-basic-use-case-of-context7-in-mcp-for-bootstrap">Basic Use Case of Context7 in MCP for Bootstrap</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-context7-mcp-for-optimal-results-with-bootstrap-5">How to Use Context7 MCP for Optimal Results with Bootstrap 5</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-by-step-build-ai-powered-landing-page-with-bootstrap-5-and-context7-mcp">Step-by-Step Build: AI-Powered Landing Page with Bootstrap 5 and Context7 MCP</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-context7-mcp-in-vs-code">How to Set Up Context7 MCP in VS Code</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-instructions-for-content-generation-and-confirmation-process">Instructions for Content Generation and Confirmation Process</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-methods-for-building-a-landing-page-with-ai">Methods for Building a Landing Page with AI</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before diving into the tutorial, make sure you have the following:</p>
<ul>
<li><p>Basic understanding of HTML, CSS, and JavaScript.</p>
</li>
<li><p>Bootstrap 5: Familiarity with this front-end framework is essential.</p>
</li>
<li><p>VS Code: A modern code editor like Visual Studio Code.</p>
</li>
<li><p>Node.js: Installed to run server-side operations.</p>
</li>
<li><p>Context7 MCP: A basic understanding of this AI-driven tool for managing design systems.</p>
</li>
</ul>
<h2 id="heading-leveraging-ai-for-bootstrap-5-landing-page-code-generation">Leveraging AI for Bootstrap 5 Landing Page Code Generation</h2>
<p>Building a landing page traditionally requires crafting HTML and CSS from scratch, which can be labor-intensive and prone to inconsistencies. That’s where AI can be helpful.</p>
<p>Tools like Context7 MCP &amp; VS Code complement this workflow by accelerating the process: with a simple prompt such as “feature card with icon and button,” it produces ready-to-use code snippets that integrate seamlessly with Bootstrap 5’s grid system and styling principles.</p>
<p>This allows developers to iterate quickly, refine their designs, and allocate more effort toward unique content and user-centric refinements.</p>
<h3 id="heading-benefits-of-using-ai-for-bootstrap-code-generation">Benefits of Using AI for Bootstrap Code Generation:</h3>
<ol>
<li><p><strong>Speed</strong>: Generate responsive, well-structured code in seconds.</p>
</li>
<li><p><strong>Efficiency</strong>: Automates boilerplate code, letting developers focus on higher-level tasks.</p>
</li>
<li><p><strong>Consistency</strong>: Ensures all generated components align with Bootstrap’s standards.</p>
</li>
<li><p><strong>Customization</strong>: Provides flexibility to tailor components to your needs.</p>
</li>
<li><p><strong>Improved and Up-to-Date AI-Generated Code</strong>: The AI follows structured guidelines, ensuring the generated code is current and accurate.</p>
</li>
</ol>
<h3 id="heading-how-ai-revolutionizes-bootstrap-development">How AI Revolutionizes Bootstrap Development</h3>
<p>AI-driven tools like Context7 MCP are not just for developers, they make web development accessible to everyone, even those without coding expertise.</p>
<p>Small business owners, digital creators, and freelancers can now create professional-grade landing pages with just a few prompts, allowing them to bring their visions to life without a steep learning curve.</p>
<h2 id="heading-what-is-bootstrap">What is Bootstrap?</h2>
<p>Bootstrap 5 is a powerful, open-source front-end framework that helps developers build responsive websites quickly. It provides a comprehensive set of components, a flexible grid system, and utility classes, making it easy to design modern, mobile-first websites with minimal effort.</p>
<p>Bootstrap is widely used for developing responsive, mobile-first websites. It offers a collection of reusable tools and components, such as navigation bars, forms, buttons, and more, which can be easily customized to meet specific project requirements.</p>
<h3 id="heading-why-choose-bootstrap-5-for-landing-pages">Why Choose Bootstrap 5 for Landing Pages?</h3>
<p>Bootstrap 5’s mobile-first approach, combined with its responsive grid system, makes it the go-to choice for building landing pages that perform seamlessly across all screen sizes.</p>
<p>The grid system, based on flexbox, enables designers to create fluid layouts that adapt to the user's viewport, ensuring that landing pages look polished on any device. With numerous utility classes for spacing, typography, and colors, developers can style pages quickly, reducing the need for custom CSS.</p>
<p>Additionally, Bootstrap 5 introduces modern CSS variables, enabling developers to easily adjust themes and style elements dynamically, perfect for projects that require quick visual updates.</p>
<p><strong>Key Bootstrap 5 Benefits for Landing Pages:</strong></p>
<ul>
<li><p><strong>Mobile-First Design</strong>: Built to prioritize mobile responsiveness, ensuring seamless performance across all devices, from phones to desktops.</p>
</li>
<li><p><strong>Extensive Component Library</strong>: A rich set of reusable, customizable components, such as buttons, alerts, forms, navigation bars, and more. This streamlines development and reduces the need for custom code.</p>
</li>
<li><p><strong>Responsive Grid System</strong>: The flexbox-based grid ensures that layouts are flexible, adaptive, and easy to modify for various screen sizes.</p>
</li>
<li><p><strong>Utility Classes</strong>: Bootstrap 5 includes a comprehensive set of utility classes for handling spacing, alignment, typography, and visibility, speeding up the styling process.</p>
</li>
<li><p><strong>Live Documentation &amp; Community Support</strong>: Bootstrap 5 offers detailed and interactive documentation, backed by a large, active community for support and resources.</p>
</li>
</ul>
<h2 id="heading-what-is-mcp"><strong>What is MCP?</strong></h2>
<p>MCP stands for Model Context Protocol. It is an open and standardized protocol designed to facilitate the interaction between large language models (LLMs) and external applications, data sources, and tools.</p>
<p>MCP enables seamless integration and contextualization, providing a uniform way for AI models to receive and understand context from various sources.</p>
<p>MCP works similarly to a universal connector, much like how USB-C serves as a common interface for connecting various devices.</p>
<p>Just as USB-C simplifies connectivity across devices, MCP streamlines the integration of LLMs with different data sources and services, ensuring smooth communication and enhancing the overall functionality of AI models.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758604936768/57e6f7b3-72c8-4c44-ae18-63bcb74c82d9.png" alt="MCP Structure" class="image--center mx-auto" width="1508" height="815" loading="lazy"></p>
<p>MCP empowers developers and organizations to build intelligent agents and complex workflows by offering the following:</p>
<ul>
<li><p><strong>Pre-built Integrations</strong>: A growing list of integrations that enable your LLM to plug into popular data sources, tools, and services without the need for custom development.</p>
</li>
<li><p><strong>Custom Integration Framework</strong>: A standardized way to create custom connections between LLMs and external services, ensuring flexibility and scalability across different use cases.</p>
</li>
<li><p><strong>Open Protocol</strong>: MCP is open-source, meaning anyone can implement and utilize it, promoting wider adoption and community-driven growth.</p>
</li>
<li><p><strong>Context Portability</strong>: MCP allows the transfer of context between various applications, making it easy to switch between services while maintaining the same level of contextual awareness across systems.</p>
</li>
</ul>
<p>By using MCP, you can build powerful AI-driven applications, automate complex workflows, and create more context-aware models that can interact seamlessly with the world around them.</p>
<h2 id="heading-basic-use-case-of-context7-in-mcp-for-bootstrap"><strong>Basic Use Case of Context7 in MCP for Bootstrap</strong></h2>
<p>When working with Bootstrap, one of the biggest challenges developers face is ensuring their code stays up-to-date with the latest version of the framework.</p>
<p>Bootstrap, like many modern front-end frameworks, undergoes frequent updates, and without access to version-specific documentation, LLMs (Large Language Models) may generate outdated or incorrect code, especially when dealing with new components or utility classes introduced in recent versions.</p>
<p>This can lead to frustrating issues, such as hallucinated code or incorrect implementation of new Bootstrap features. Manual efforts to update documentation or reference various sources are often time-consuming and inefficient, with the added challenge of keeping track of specific version differences across the framework’s evolution.</p>
<h3 id="heading-the-solution-context7-for-bootstrap">The Solution: Context7 for Bootstrap</h3>
<blockquote>
<p>Clean, version-specific Bootstrap documentation for accurate, up-to-date code generation.</p>
</blockquote>
<p>Context7 eliminates these issues by providing real-time, version-specific documentation directly to your AI tools, ensuring they always have the most accurate and relevant Bootstrap code. With Context7, you can be confident that the AI-generated code is fully aligned with the current version of Bootstrap, streamlining the development process and ensuring upto the mark implementation of the framework.</p>
<p><strong>Key Features of Context7 for Bootstrap:</strong></p>
<ul>
<li><p><strong>Version-Specific Bootstrap Documentation</strong>: Always up-to-date with the latest Bootstrap version, ensuring accurate integration of new classes, components, and utilities.</p>
</li>
<li><p><strong>Real, Working Bootstrap Code</strong>: Extracts working examples directly from official Bootstrap documentation, saving you time and effort.</p>
</li>
<li><p><strong>Concise and Relevant Information</strong>: Filters out unnecessary details and ensures you receive only the most useful snippets for your project.</p>
</li>
<li><p><strong>Free for Personal Use</strong>: Access the powerful Context7 tool without any cost for personal development and experimentation.</p>
</li>
<li><p><strong>MCP Integration</strong>: Seamlessly integrates with Model Context Protocol (MCP) to provide context-aware AI interactions, making it easier for developers to work with Bootstrap in real-time.</p>
</li>
</ul>
<h2 id="heading-how-to-use-context7-mcp-for-optimal-results-with-bootstrap-5">How to Use Context7 MCP for Optimal Results with Bootstrap 5</h2>
<p>When building responsive and modern landing pages, developers often face limitations with tools like Lovable and Bolt. These platforms typically provide pre-built templates, but they can restrict customization and integration, especially when working with powerful front-end frameworks like Bootstrap 5.</p>
<p>Unlike traditional solutions, Context7 MCP integrates with the most current official Bootstrap 5 documentation, providing real-time access to the latest framework updates, components, and best practices.</p>
<p>This feature is essential, as it ensures that the generated code adheres to Bootstrap 5’s latest standards, offering a far more flexible and accurate approach than static templates or LLM-based solutions, which might not reflect the most recent changes in Bootstrap 5.</p>
<p><strong>With Context7 MCP, you gain:</strong></p>
<ul>
<li><p><strong>Flexibility</strong>: Effortlessly generate custom Bootstrap 5 components tailored to your specific needs, such as navigation bars, buttons, or modals.</p>
</li>
<li><p><strong>Seamless Bootstrap 5 Integration</strong>: Fully integrate with Bootstrap 5’s responsive grid system and design conventions, ensuring your landing pages are both functional and adaptive to different screen sizes.</p>
</li>
<li><p><strong>Consistency</strong>: Maintain design consistency across your project without compromising on customization, leveraging the latest components and utilities directly from Bootstrap 5.</p>
</li>
<li><p><strong>Up-to-Date Components</strong>: Always have access to the latest Bootstrap 5 features and updates from MCP, ensuring that your landing pages are current with the latest changes in the framework.</p>
</li>
</ul>
<h3 id="heading-how-context7-mcp-enhances-productivity">How <strong>Context7 MCP</strong> Enhances Productivity</h3>
<p>By incorporating Context7 MCP into your development workflow, you streamline the process of building responsive landing pages and web applications.</p>
<p>Context7 MCP ensures that all your components align with latest Bootstrap 5 standards, making it easier to maintain consistency throughout your project.</p>
<p>This allows you to quickly adapt to the latest Bootstrap 5 updates, leveraging its latest features without the risk of introducing errors or inconsistencies.</p>
<h2 id="heading-step-by-step-build-ai-powered-landing-page-with-bootstrap-5-and-context7-mcp">Step-by-Step Build: AI-Powered Landing Page with Bootstrap 5 and Context7 MCP</h2>
<p>In this guide, we will walk through building an engaging <strong>AI-powered landing page</strong> using <strong>Context7 MCP</strong> and <strong>Bootstrap 5</strong>. We will cover everything from setting up the project environment to generating responsive Bootstrap components and integrating AI-powered elements to enhance user experience.</p>
<h3 id="heading-set-up-the-project-environment">Set Up the Project Environment</h3>
<p>Before we dive into creating the landing page, we’ll start by setting up the project structure and ensuring that we have Bootstrap 5 integrated. Additionally, we will leverage Context7 MCP to automate the generation of responsive components and layouts for the landing page.</p>
<h4 id="heading-1-set-up-the-project-folder">1. Set up the project folder:</h4>
<pre><code class="lang-bash">mkdir my-landing-page
<span class="hljs-built_in">cd</span> my-landing-page
</code></pre>
<p>Create the <code>index.html</code> file for the landing page layout:</p>
<pre><code class="lang-bash">touch index.html
</code></pre>
<p>Initialize the project with <code>npm</code>:</p>
<pre><code class="lang-bash">npm init -y
</code></pre>
<p>This will create a <code>package.json</code> file for the project.</p>
<h4 id="heading-2-add-bootstrap-5-to-the-project">2. Add Bootstrap 5 to the project:</h4>
<p>You can include Bootstrap 5 in two ways: by downloading the compiled CSS and JS files or by using a CDN. For simplicity, we’ll use the CDN links.</p>
<p>In the <code>&lt;head&gt;</code> section of your <code>index.html</code>, add:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"&lt;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&gt;"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span>&gt;</span>
</code></pre>
<p>At the end of the <code>&lt;body&gt;</code> section, add:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"&lt;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js&gt;"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>This ensures that Bootstrap 5 is integrated into the project for layout and component styling.</p>
<h4 id="heading-3-basic-structure-of-the-landing-page">3. Basic Structure of the Landing Page:</h4>
<p>Start by setting up the basic layout in your <code>index.html</code> file:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Landing Page<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- Bootstrap 5 CDN --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"&lt;https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css&gt;"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- Landing Page Content --&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"&lt;https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js&gt;"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>This simple structure sets the stage for a responsive design. Feel free to modify the content as per your requirements.</p>
<h2 id="heading-how-to-set-up-context7-mcp-in-vs-code">How to Set Up <strong>Context7</strong> MCP in VS Code</h2>
<p>Integrating Context7 MCP into your project is an essential step to streamline your development process, allowing seamless interaction with large language models (LLMs) and ensuring the generation of accurate, context-driven code. Below is a step-by-step guide on how to set up Context7 MCP in VS Code.</p>
<h3 id="heading-1-one-click-setup-optional"><strong>1. One-Click Setup (Optional)</strong></h3>
<p>For a quick and easy installation, you can use the one-click setup to install Context7 MCP in VS Code. Simply click the link below to initiate the installation:</p>
<p><a target="_blank" href="https://insiders.vscode.dev/redirect?url=vscode:mcp%2Finstall?%7B%22name%22:%22context7%22,%22command%22:%22npx%22,%22args%22:%5B%22-y%22,%22@upstash%2Fcontext7-mcp@latest%22%5D%7D&amp;utm_source=chatgpt.com">Install Context7 MCP in VS Code</a></p>
<p>This will automatically install Context7 MCP for you within VS Code, enabling it for use in your development environment.</p>
<h3 id="heading-2-add-mcp-configuration-to-vs-code"><strong>2. Add MCP Configuration to VS Code</strong></h3>
<p>Once Context7 MCP is installed, you’ll need to configure it within VS Code. This step ensures that VS Code communicates with the MCP server to fetch context-driven documentation and code examples.</p>
<p>To add the configuration, follow these steps:</p>
<ol>
<li><p>Open the <code>settings.json</code> file in VS Code by navigating to <code>File</code> &gt; <code>Preferences</code> &gt; <code>Settings</code> and clicking the {} Open Settings (JSON) icon.</p>
</li>
<li><p>Add the following MCP configuration to the settings file:</p>
</li>
</ol>
<pre><code class="lang-json"><span class="hljs-string">"mcp"</span>: {
  <span class="hljs-attr">"servers"</span>: {
    <span class="hljs-attr">"context7"</span>: {
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"http"</span>,
      <span class="hljs-attr">"url"</span>: <span class="hljs-string">"&lt;https://mcp.context7.com/mcp&gt;"</span>,
      <span class="hljs-attr">"headers"</span>: {
        <span class="hljs-attr">"CONTEXT7_API_KEY"</span>: <span class="hljs-string">"YOUR_API_KEY"</span>
      }
    }
  }
}
</code></pre>
<p>Replace <code>"YOUR_API_KEY"</code> with your actual API key from Context7. This key will authenticate your request and allow access to MCP services.</p>
<h3 id="heading-3-local-server-setup"><strong>3. Local Server Setup</strong></h3>
<p>If you prefer running Context7 MCP locally rather than using the hosted version, you can set up a local server. This is especially useful for working in isolated environments or without an internet connection.</p>
<p><strong>To configure Context7 MCP to run locally:</strong></p>
<ol>
<li><p>Open your <code>settings.json</code> file in VS Code.</p>
</li>
<li><p>Add the following configuration:</p>
</li>
</ol>
<pre><code class="lang-json"><span class="hljs-string">"mcp"</span>: {
  <span class="hljs-attr">"servers"</span>: {
    <span class="hljs-attr">"context7"</span>: {
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"stdio"</span>,
      <span class="hljs-attr">"command"</span>: <span class="hljs-string">"npx"</span>,
      <span class="hljs-attr">"args"</span>: [<span class="hljs-string">"-y"</span>, <span class="hljs-string">"@upstash/context7-mcp"</span>, <span class="hljs-string">"--api-key"</span>, <span class="hljs-string">"YOUR_API_KEY"</span>]
    }
  }
}
</code></pre>
<p>This setup runs Context7 MCP locally by invoking the <code>npx</code> command with the necessary arguments, including your API key.</p>
<h3 id="heading-4-installing-context7-in-other-editors"><strong>4. Installing Context7 in Other Editors</strong></h3>
<p>If you wish to set up Context7 MCP in other code editors, you can follow detailed installation guidelines available in the <a target="_blank" href="https://github.com/upstash/context7?tab=readme-ov-file&amp;utm_source=chatgpt.com#%EF%B8%8F-installation">Context7 Installation Documentation</a>. This resource provides step-by-step instructions for configuring MCP in various environments, ensuring compatibility with your preferred editor.</p>
<h2 id="heading-instructions-for-content-generation-and-confirmation-process">Instructions for Content Generation and Confirmation Process</h2>
<p>To begin generating content with Context7 MCP, you first need to confirm whether you'd like to proceed with the provided context. If you're using the context I've shared, simply click 'Continue' to confirm your choice.</p>
<p>A second confirmation will ensure that you want to generate content based on the prompt provided. Once you click 'Continue', the system will refer to the appropriate context (for example, Bootstrap documentation) and initiate the content generation process.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758609079268/c0767ab9-0950-4055-a875-315e95af8cfb.png" alt="content generation &amp; confirmation process.png" class="image--center mx-auto" width="401" height="409" loading="lazy"></p>
<p><strong>Note:</strong> When writing a prompt and intending to use Context7, make sure to include <code>using context7</code> at the beginning of the prompt. This explicitly directs the AI to generate content based on Model Context Protocol (MCP) and relevant context sources like Bootstrap 5 documentation.</p>
<h3 id="heading-how-to-automate-the-inclusion-of-context7-instructions"><strong>How to Automate the Inclusion of Context7 Instructions</strong></h3>
<p>If you'd like to avoid manually including the <code>using context7</code> instruction in every prompt, you can automate the process by setting default instructions in your project’s configuration files. To do this, add the following instructions to your <code>.github/copilot-instructions.md</code> file in the root directory of your project:</p>
<pre><code class="lang-html">always use context7 with bootstrap
</code></pre>
<h2 id="heading-methods-for-building-a-landing-page-with-ai">Methods for Building a Landing Page with AI</h2>
<h3 id="heading-1-building-a-complete-landing-page-with-a-single-prompt">1. Building a Complete Landing Page with a Single Prompt</h3>
<p>An effective landing page is not just about design, it must provide a seamless, user-friendly experience that immediately captures attention and guides visitors through the content.</p>
<p>By leveraging the flexibility of Bootstrap 5 and the power of the Context7 MCP framework, you can generate a complete, fully responsive landing page that performs well across all devices, both mobile and desktop.</p>
<p>Using a single prompt, you can quickly create a comprehensive layout with all essential sections, streamlining the process while maintaining visual appeal and functional design.</p>
<p><strong>Important Note:</strong> When generating a complete landing page layout, results may vary depending on different environments or agents. While creating a full-page design using a single prompt can yield some results, the precision and consistency may not be as high compared to generating individual sections. For more consistent and accurate results, consider using advanced models like Claude Sonnet 4 to ensure better output quality.</p>
<h4 id="heading-creating-a-responsive-ai-tool-landing-page">Creating a Responsive AI Tool Landing Page</h4>
<p>Here’s a template for building a responsive and dynamic landing page layout using Bootstrap 5, ensuring that all key sections are optimized for both mobile and desktop views:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758609225968/6687f86b-12a2-46c4-b56e-7a7669b49206.png" alt="AI landing page example" class="image--center mx-auto" width="1905" height="934" loading="lazy"></p>
<pre><code class="lang-html">Generate a responsive AI tool landing page layout with Bootstrap 5 featuring the following sections:
- Navigation Bar: Links to other sections of the page.
- Hero Section: A heading, subheading, and a compelling call-to-action button.
- About Section: Introduces the company or product.
- Features Section: Highlights key features and benefits.
- How It Works Section: Explains the process or flow.
- Pricing Section: Showcases pricing plans or offers.
- FAQ Section: Answers common questions and concerns.
- Contact Section: Provides contact details or an inquiry form.
- Footer Section: Includes copyright and additional links.
</code></pre>
<p>This structure ensures a logical flow, starting with an engaging Hero Section, followed by deeper insights into the product (Features, How It Works), and finishing with clear calls to action (Pricing, FAQ, and Contact).</p>
<p><strong>Code Example</strong></p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/smitbhalodiya/embed/LEpMEON" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>You can access all the code for this landing page by cloning or downloading the repository:</p>
<p><a target="_blank" href="https://github.com/themeselection/bootstrap-landing-page"><strong>Repository Link</strong></a></p>
<p>For the complete code, including the full layout template, visit the <code>full-prompt-landing-page.html</code> file in the repository directly:</p>
<p><a target="_blank" href="https://github.com/themeselection/bootstrap-landing-page/blob/main/full-prompt-landing-page.html?"><strong>Full Code File</strong></a></p>
<h3 id="heading-2-creating-a-section-by-section-landing-page">2. Creating a Section-by-Section Landing Page</h3>
<p>Building a landing page section by section allows you to focus on each component individually, ensuring precise control over design and functionality.</p>
<p>By structuring your page into distinct sections (such as the hero, features, pricing, and so on), you can tailor the content and style of each part, ensuring that it aligns with your branding and conversion goals.</p>
<p>This method provides greater flexibility and customization, especially when using AI-powered tools like Context7 MCP, as it allows you to generate each section according to specific requirements and design preferences.</p>
<h4 id="heading-create-a-header-and-hero-section-with-ai-prompt">Create a Header and Hero Section with AI Prompt</h4>
<p>The Header and Hero Section are essential for setting the tone of your landing page. The hero section grabs visitors' attention immediately and introduces them to the key value proposition of your AI tool. The header ensures smooth navigation across the page.</p>
<p><strong>Prompt Example:</strong></p>
<p>"Design a full-width hero section with a striking background image or color that highlights the AI tool. Include a compelling tagline that clearly communicates the main benefit of the tool, along with a call-to-action (CTA) button prompting users to 'Get Started' or 'Learn More.' Additionally, create a clean, responsive header section with a navigation bar containing links to: Home, About, Features, Pricing, FAQ, and Contact."</p>
<p><strong>AI Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758610136433/ffcdc65b-3643-4db9-adbb-63558913a013.png" alt="header &amp; hero section example" class="image--center mx-auto" width="1905" height="935" loading="lazy"></p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codesandbox.io/embed/clxsvl?view=editor+%2B+preview" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodeSandbox embed" allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin" loading="lazy"></iframe></div>
<p> </p>
<p><strong>Customizing the Style:</strong></p>
<p>To further customize the style, you can adjust the background, font, and button classes either through the prompt or by manually editing the class names in the generated code. With MCP, you can also tweak colors and typography to better align with your brand's design guidelines.</p>
<h4 id="heading-create-an-engaging-about-section-with-ai-prompt">Create an Engaging About Section with AI Prompt</h4>
<p>The About section serves as an introduction to your AI tool, explaining its purpose, key features, and how it benefits users. It should establish trust and clearly communicate what makes your tool unique.</p>
<p><strong>Prompt Example:</strong></p>
<p>"Design an 'About' section with a brief overview of the AI tool. Include a short paragraph explaining the tool’s core features, its purpose, and how it stands out from competitors. Add an image or icon to visually complement the text."</p>
<p><strong>AI Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758610832403/11aec6be-b98a-4612-b680-a52748a2b9d6.png" alt="about section example" class="image--center mx-auto" width="1499" height="747" loading="lazy"></p>
<p><strong>Customizing the Style:</strong></p>
<p>You can adjust the background, typography, and button classes to fit your brand's aesthetic. Modify the content to better highlight the unique selling points of your AI tool, ensuring that it resonates with your target audience.</p>
<h4 id="heading-showcase-key-features-with-ai-prompt">Showcase Key Features with AI Prompt</h4>
<p>The Features section is essential for highlighting the core benefits and capabilities of your AI tool. It helps users understand exactly what the tool offers and how it can improve their workflow or solve their problems.</p>
<p><strong>Prompt Example:</strong></p>
<p>"Design a Features section that lists the key features of the AI tool in a visually engaging manner. Include icons or images to represent each feature and provide short, clear descriptions of how each feature benefits the user. Ensure the section is easy to scan and encourages users to explore more."</p>
<p><strong>AI Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758610934605/b3246eb3-15dd-4d89-b1bd-7ee465a863d4.png" alt="key features showcase example" class="image--center mx-auto" width="1012" height="764" loading="lazy"></p>
<p><strong>Customizing the Style:</strong></p>
<p>You can easily adjust the icons, typography, and layout using the prompt or by editing the class names in the generated markup. Consider using your brand’s icons or color palette to make the section more visually aligned with your brand identity. You can also tweak the descriptions to focus on the features most important to your target audience.</p>
<h4 id="heading-present-pricing-plans-with-ai-prompt">Present Pricing Plans with AI Prompt</h4>
<p>The Pricing section is crucial for converting visitors into customers. It should clearly display the available pricing options, highlighting the value of each plan and encouraging users to take action. This section should be simple, yet persuasive, and easy to understand.</p>
<p><strong>Prompt Example:</strong></p>
<p>"Design a Pricing section that clearly presents different pricing tiers. Include the plan names, prices, key features, and a clear call-to-action (CTA) button for each plan. Use a comparison table or card layout to make it easy for users to compare options and make an informed decision."</p>
<p><strong>AI Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758611081962/078de2d2-238f-4164-a859-300ac284e6c3.png" alt="pricing example" class="image--center mx-auto" width="1241" height="853" loading="lazy"></p>
<p><strong>Customizing the Style:</strong></p>
<p>To tailor the Pricing section to your brand, you can adjust the colors, fonts, and card styles. You can customize the pricing plans to fit your offering, modify the CTA buttons to highlight specific actions (for example, “Start Free Trial” or “Learn More”), and adjust the layout for different screen sizes.</p>
<h4 id="heading-create-an-informative-faq-section-with-ai-prompt">Create an Informative FAQ Section with AI Prompt</h4>
<p>The FAQ section is key to addressing common questions and concerns from potential users, helping them make informed decisions. It should be organized, easy to scan, and provide clear, concise answers. This section can also reduce customer support inquiries by offering quick solutions.</p>
<p><strong>Prompt Example:</strong></p>
<p>"Design a FAQ section that addresses common questions about the AI tool. Use an accordion or collapsible design for better readability, and ensure the answers are concise and informative. Include a clear, inviting heading for the section and format the questions in a way that’s easy to scan."</p>
<p><strong>AI Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758611141685/55f196ed-ce62-44ad-93c4-e71d06160084.png" alt="FAQ section example" class="image--center mx-auto" width="1250" height="847" loading="lazy"></p>
<p><strong>Customizing the Style:</strong></p>
<p>You can personalize the FAQ section by adjusting the accordion style, colors, and fonts to match your brand’s theme. You can also modify the questions and answers based on the most common inquiries from your users. For a more dynamic effect, consider adding icons or images next to the questions.</p>
<h4 id="heading-create-an-engaging-contact-section-with-ai-prompt">Create an Engaging Contact Section with AI Prompt</h4>
<p>The Contact section is essential for encouraging visitors to reach out for more information, support, or inquiries. It should be clear, easy to use, and include all necessary contact details, as well as a form for quick communication.</p>
<p><strong>Prompt Example:</strong></p>
<p>"Design a Contact section that includes a contact form with fields for name, email, subject, and message. Ensure the form is simple, easy to fill out, and includes a submit button. Also, provide clear contact details, such as a phone number, email address, and physical location (if applicable)."</p>
<p><strong>AI Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758611619369/87e47a01-fddd-48af-9230-f597d40a932a.png" alt="contact section example" class="image--center mx-auto" width="1341" height="809" loading="lazy"></p>
<p><strong>Customizing the Style:</strong></p>
<p>To align the Contact section with your brand’s design, you can modify the colors, fonts, and form styles. Adjust the form fields, buttons, and layout to match the look and feel of your website.</p>
<p>Additionally, you can add custom map integration or contact methods (like social media handles) to further enhance accessibility.</p>
<h4 id="heading-create-a-comprehensive-footer-section-with-ai-prompt">Create a Comprehensive Footer Section with AI Prompt</h4>
<p>The Footer section is often the last thing users see on a page, so it’s essential to include important links, contact details, and legal information. A well-designed footer can help improve site navigation and encourage further engagement with your content.</p>
<p><strong>Prompt Example:</strong></p>
<p>"Design a Footer section that includes key navigation links, such as Privacy Policy, Terms of Service, and social media icons (for example, Facebook, Twitter, LinkedIn). Include your company’s contact details (email, phone) and a copyright notice. The footer should be responsive and neatly organized."</p>
<p><strong>AI Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758611686647/47902f6c-2472-4a1e-b2b9-a42c3ebc6414.png" alt="footer example" class="image--center mx-auto" width="1904" height="532" loading="lazy"></p>
<p><strong>Customizing the Style:</strong></p>
<p>To match your brand’s aesthetics, you can adjust the Footer section’s background color, typography, and icon styles. You can also add additional links like your blog, careers page, or a newsletter signup form. Ensure the footer is responsive by checking it on different screen sizes, making adjustments to spacing or layout as needed.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, we’ve demonstrated how to create a modern, responsive landing page using Bootstrap 5 and integrate Context7 MCP. We also explored different methods for building the landing page, either using a single comprehensive prompt or constructing it section by section.</p>
<p>While a single comprehensive prompt can generate a landing page quickly, building it section by section typically yields better results. This approach allows for greater customization, finer control over each element, and ensures that every section aligns with your overall design vision.</p>
<p>By leveraging Bootstrap 5’s robust grid system and Context7’s AI-driven component generation, you can easily create landing pages that are not only visually appealing but also responsive and functional across all devices. This combination of tools makes the process faster, more efficient, and scalable.</p>
<p>You can also consider using a ready made <a target="_blank" href="https://themeselection.com/item/category/bootstrap-templates/">bootstrap template</a> which comes with pre designed landing pages.</p>
<p><strong>With this setup, you can expect:</strong></p>
<p>Rather than requiring developers to manually write repetitive code for common components, such as navigation bars, feature cards, or grids, VS Code and Context7 automates this process, allowing you to focus on higher-level design decisions.</p>
<p>It also ensures that the generated code is fully responsive and in alignment with latest Bootstrap 5’s framework, providing seamless integration with Bootstrap’s utilities like spacing, alignment, and visibility.</p>
<p>I hope you find this article helpful and worth reading. I have prepared this article with help of <a target="_blank" href="https://github.com/smitbhalodiya">Smit Bhalodiya</a>, a Front End developer with 5+ years of experience in the field.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Integrate Tailwind with Electron – With Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ In this article, you’ll learn how to integrate Tailwind CSS with Electron to build stylish, responsive desktop applications. You’ll set up Tailwind in an Electron project, configure your project, style the components, and optimize the development wor... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/integrate-tailwind-with-electron/</link>
                <guid isPermaLink="false">689cc9ce08eeb0d54c95cff1</guid>
                
                    <category>
                        <![CDATA[ Tailwind CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Electron ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abhijeet Dave ]]>
                </dc:creator>
                <pubDate>Wed, 13 Aug 2025 17:22:22 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1755102784797/0a2d19f0-3539-47c6-a29d-68fab3d430ba.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, you’ll learn how to integrate Tailwind CSS with Electron to build stylish, responsive desktop applications.</p>
<p>You’ll set up Tailwind in an Electron project, configure your project, style the components, and optimize the development workflow. This is perfect for developers who are looking to combine Tailwind's utility-first CSS framework with Electron's cross-platform capabilities.</p>
<h2 id="heading-table-of-content">Table of Content</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-a-quick-overview-of-electron">A Quick Overview of Electron</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-tailwind-css">What is Tailwind CSS?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-electron-and-tailwind-work-so-well-together">Why Electron and Tailwind Work So Well Together</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-well-build">What We’ll Build?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-initialize-an-electron-project">How to Initialize an Electron Project</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-integrate-tailwind-css-with-electron">How to Integrate Tailwind CSS with Electron?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-a-tailwind-component-library-a-practical-example">How to Use a Tailwind Component Library – a Practical Example</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-lets-test-flyonui-js-components">Let’s Test FlyonUI JS Components</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-a-quick-overview-of-electron">A Quick Overview of Electron</h2>
<p><a target="_blank" href="https://www.electronjs.org/"><strong>Electron</strong></a> is a framework that lets developers create desktop applications for Windows, macOS, and Linux using familiar web technologies like HTML, CSS, and JavaScript, along with Node.js for backend features.</p>
<p>It's open-source, MIT-licensed, and completely free to use – whether you're building personal projects or commercial apps.</p>
<p>In this guide, we’ll look at why so many developers and companies choose Electron for building modern desktop apps.</p>
<h2 id="heading-what-is-tailwind-css"><strong>What is Tailwind CSS?</strong></h2>
<p><a target="_blank" href="https://tailwindcss.com/"><strong>Tailwind CSS</strong></a> is essentially a utility-first framework for styling web interfaces. Unlike frameworks that provide full-blown, pre-designed UI components, Tailwind offers a comprehensive set of single-purpose utility classes. You apply these classes directly to your HTML elements, which means you can rapidly build out custom layouts and designs without diving into separate CSS files.</p>
<p>The big advantage? Precision and flexibility – you can assemble unique, responsive interfaces by combining these classes however you see fit, all while keeping you markup lean and maintainable.</p>
<h2 id="heading-why-electron-and-tailwind-work-so-well-together"><strong>Why Electron and Tailwind Work So Well Together</strong></h2>
<p>Electron uses HTML, CSS, and JavaScript to build desktop applications. Essentially, it runs a web app in a desktop shell. This makes it easy to integrate modern frontend tools like Tailwind CSS.</p>
<p>Tailwind's utility-first approach allows you to style interfaces directly in you HTML, which can speed up UI development. Instead of writing custom styles or managing large CSS files, you apply predefined classes directly to elements. This aligns well with Electron's structure, where layout and styles are tightly connected within the same HTML environment.</p>
<p>Tailwind also provides sensible defaults and a consistent design system out of the box. This helps you prototype and build visually consistent desktop apps faster. While some familiarity with CSS is still helpful, Tailwind's approach can reduce the overhead of setting up and managing styles, especially in smaller or design-light projects.</p>
<p>Together, Electron and Tailwind offer a straightforward path to building desktop apps.</p>
<h2 id="heading-what-well-build">What We’ll Build?</h2>
<p>In this tutorial, we will create a basic Electron desktop app styled with Tailwind CSS and improved with FlyonUI components. You don’t need any prior experience with Electron or Tailwind.</p>
<p>By the end of the guide, you'll have:</p>
<ul>
<li><p>A working desktop window (Electron)</p>
</li>
<li><p>Styled UI with Tailwind CSS</p>
</li>
<li><p>A reusable button component</p>
</li>
<li><p>A fully functional modal dialog powered by FlyonUI</p>
</li>
</ul>
<p>This will provide a solid base for building more complex apps in the future.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>Before we dive in, make sure you have the following:</p>
<ul>
<li><p><strong>Basic knowledge of HTML, CSS, and JavaScript</strong>. You don’t need to be an expert, but understanding how to structure HTML and use basic JavaScript will help you follow along.</p>
</li>
<li><p><strong>Familiarity with Node.js and npm</strong>. We'll use npm (Node Package Manager) to install dependencies and run build commands.</p>
</li>
<li><p><strong>Node.js installed on your machine</strong>. You can download it from <a target="_blank" href="http://nodejs.org">nodejs.org</a><a target="_blank" href="https://nodejs.org/">.</a></p>
</li>
<li><p><strong>A code editor</strong>. I recommend <a target="_blank" href="https://code.visualstudio.com/">Visual Studio Code.</a></p>
</li>
<li><p><strong>Terminal / Command Line Access</strong>. You’ll need to run commands in the terminal to set things up.</p>
</li>
</ul>
<h2 id="heading-how-to-initialize-an-electron-project"><strong>How to Initialize an Electron Project</strong></h2>
<p>Let’s set up a basic Electron app from scratch. This will launch a simple desktop window that loads an HTML file, serving as the foundation for your UI.</p>
<h3 id="heading-1-create-your-project-folder">1. <strong>Create Your Project Folder</strong></h3>
<p>First, open your terminal and create a new project folder:</p>
<pre><code class="lang-bash">mkdir my-electron-app
<span class="hljs-built_in">cd</span> my-electron-app
</code></pre>
<p>This creates a new folder called <code>my-electron-app</code> and changes the directory to it. This folder will be your project workspace.</p>
<h3 id="heading-2-install-electron">2. <strong>Install Electron</strong></h3>
<p>Next, install Electron as a development dependency:</p>
<pre><code class="lang-bash">npm install electron --save-dev
</code></pre>
<p>This will add Electron to your project’s <code>node_modules</code> and update your <code>package.json</code> file.</p>
<p>This command installs Electron as a development dependency. Electron allows you to build desktop apps across different platforms using web technologies like HTML, CSS, and JavaScript.</p>
<h3 id="heading-3-configure-packagejson">3. <strong>Configure</strong> <code>package.json</code></h3>
<p>Update your <code>package.json</code> to point to a file named <code>main.js</code>, and add a script for easily starting the app.</p>
<p><strong>Edit your</strong> <code>package.json</code> like this:</p>
<pre><code class="lang-json"><span class="hljs-string">"main"</span>: <span class="hljs-string">"main.js"</span>,
<span class="hljs-string">"scripts"</span>: {
  <span class="hljs-attr">"start"</span>: <span class="hljs-string">"electron ."</span>
}
</code></pre>
<ul>
<li><p><code>"main"</code> defines the entry point of your Electron app (the main process).</p>
</li>
<li><p><code>"start"</code> is a shortcut to launch the app using <code>npm start</code>.</p>
</li>
</ul>
<h3 id="heading-4-create-mainjs">4. <strong>Create</strong> <code>main.js</code></h3>
<p>Create a file named <code>main.js</code> in your root folder and add the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { app, BrowserWindow } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"electron/main"</span>);

<span class="hljs-keyword">const</span> createWindow = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> win = <span class="hljs-keyword">new</span> BrowserWindow({
    <span class="hljs-attr">width</span>: <span class="hljs-number">800</span>,
    <span class="hljs-attr">height</span>: <span class="hljs-number">600</span>,
  });

  win.loadFile(<span class="hljs-string">"index.html"</span>);
};

app.whenReady().then(<span class="hljs-function">() =&gt;</span> {
  createWindow();

  app.on(<span class="hljs-string">"activate"</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (BrowserWindow.getAllWindows().length === <span class="hljs-number">0</span>) {
      createWindow();
    }
  });
});

app.on(<span class="hljs-string">"window-all-closed"</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">if</span> (process.platform !== <span class="hljs-string">"darwin"</span>) {
    app.quit();
  }
});
</code></pre>
<p>This is your <strong>main process</strong>. It creates and manages the app window while loading your HTML file.</p>
<h3 id="heading-5-create-indexhtml-renderer-process">5. <strong>Create</strong> <code>index.html</code> <strong>(Renderer Process)</strong></h3>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"Content-Security-Policy"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"default-src 'self'; script-src 'self'"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Hello from Electron renderer!<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello from Electron renderer!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"info"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./renderer.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>This is the <strong>frontend (renderer)</strong> of your Electron app. You can use standard HTML, CSS, and JavaScript here, just like in a browser.</p>
<blockquote>
<p>Optional: Create a renderer.js file if you want to add JavaScript interactivity.</p>
</blockquote>
<h3 id="heading-6-run-the-electron-app">6. <strong>Run the Electron App</strong></h3>
<p>Now, create a file called <code>main.js</code> in the root of your project. This is the main process that starts your Electron app:</p>
<pre><code class="lang-bash">npm start
</code></pre>
<p>This command runs the app using the script you set up in <code>package.json</code>. A desktop window should open, displaying your HTML content.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754292319523/58168908-40ed-4aca-920f-fbab7435b580.webp" alt="hello form electron renderer" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-integrate-tailwind-css-with-electron"><strong>How to Integrate Tailwind CSS with Electron?</strong></h2>
<p>For this guide, we’ll be using the <a target="_blank" href="https://tailwindcss.com/docs/installation/tailwind-cli">Tailwind CLI</a> approach.</p>
<p>The Tailwind CLI is a command-line tool that allows you to generate and compile Tailwind utility classes directly into a CSS file. You don’t need complex build tools like Webpack or PostCSS. This makes it perfect for simple projects like Electron apps, where you’d want minimal setup and quick styling. The CLI also has a <code>--watch</code> mode that automatically rebuilds CSS when files change. This feature helps you stay productive.</p>
<h3 id="heading-1-install-tailwind-css">1. <strong>Install Tailwind CSS</strong></h3>
<p>First, install Tailwind CSS. Make sure Node.js is installed as well, then run:</p>
<pre><code class="lang-bash">npm install tailwindcss @tailwindcss/cli
</code></pre>
<p>This command installs Tailwind and its CLI tool as a development dependency in your project. We’ll use the CLI to build and monitor our Tailwind styles.</p>
<h3 id="heading-2-set-up-tailwind-css">2. <strong>Set Up Tailwind CSS</strong></h3>
<p>Create a <code>input.css</code> file with the following content to set up Tailwind:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@import</span> <span class="hljs-string">"tailwindcss"</span>;
</code></pre>
<p>This line instructs Tailwind to generate all its utility classes into one output file, which we’ll compile next.</p>
<h3 id="heading-3-add-a-build-script">3. <strong>Add a Build Script</strong></h3>
<p>Then update your <code>package.json</code> to include a build script:</p>
<pre><code class="lang-json"><span class="hljs-string">"scripts"</span>: {  
 <span class="hljs-attr">"watch:css"</span>:<span class="hljs-string">"npx @tailwindcss/cli -i ./input.css -o ./output.css --watch"</span>,
}
</code></pre>
<p>This command watches your <code>input.css</code> file and continuously builds a compiled CSS file (<code>output.css</code>) whenever it detects changes. You’ll include this file in your HTML.</p>
<h3 id="heading-4-link-outputcss-in-indexhtml">4. <strong>Link</strong> <code>output.css</code> <strong>in</strong> <code>index.html</code></h3>
<p>Open your <code>index.html</code> file and add this inside the <code>&lt;head&gt;</code></p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"./output.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span>&gt;</span>
</code></pre>
<p>Then compile Tailwind CSS with this command:</p>
<pre><code class="lang-bash">npm run watch:css
</code></pre>
<p>This step includes the compiled Tailwind styles in your Electron app UI.</p>
<h3 id="heading-5-compile-tailwind-css">5. <strong>Compile Tailwind CSS</strong></h3>
<p>Run this script to start watching for changes and generate your CSS:</p>
<pre><code class="lang-bash">npm run watch:css
</code></pre>
<p>Keep this process running in a terminal window. It updates <code>output.css</code> live as you work.</p>
<h3 id="heading-6-update-the-ui-with-tailwind-classes">6. <strong>Update the UI with Tailwind Classes</strong></h3>
<p>Replace your <code>&lt;body&gt;</code> content with this example layout:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex items-center justify-center h-screen bg-gray-100"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span>
    <span class="hljs-attr">class</span>=<span class="hljs-string">"py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-purple-600 text-white hover:bg-purple-700 focus:outline-hidden cursor-pointer focus:bg-purple-700 disabled:opacity-50 disabled:pointer-events-none"</span>&gt;</span>
    Hello Tailwindcss
  <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<h3 id="heading-7-run-the-electron-app">7. <strong>Run the Electron App</strong></h3>
<p>Run the electron server with this command:</p>
<pre><code class="lang-bash">npm start
</code></pre>
<p>Your Electron window should now open with a well-styled button in the center, thanks to Tailwind CSS.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754374369750/f79a6c6d-bc59-4a2b-a6eb-f3b63f8bccc4.png" alt="run electron server" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-use-a-tailwind-component-library-a-practical-example">How to Use a Tailwind Component Library – a Practical Example</h2>
<p>We are going to use <a target="_blank" href="https://flyonui.com/">FlyonUI</a>, an open source Tailwind component library. It includes a mix of utility classes in addition to JavaScript plugins. FlyonUI draws ideas from daisyUI but also from Preline, and combines flexibility and simplicity. It also helps you build interfaces that respond well and appear consistent.</p>
<h3 id="heading-1-install-flyonui">1. <strong>Install FlyonUI</strong></h3>
<p>You can install FlyonUI with the command below. Make sure Node.js is installed, then run:</p>
<pre><code class="lang-bash">npm install -D flyonui@latest
</code></pre>
<p>Installs FlyonUI into your project as a development dependency, making its CSS and JS functionality available for integration.</p>
<h3 id="heading-2-add-flyonui-as-plugin-in-the-inputcss">2. Add FlyonUI as plugin in the <code>input.css</code>:</h3>
<pre><code class="lang-css"><span class="hljs-keyword">@import</span> <span class="hljs-string">"tailwindcss"</span>;
<span class="hljs-keyword">@plugin</span> <span class="hljs-string">"flyonui"</span>;
<span class="hljs-keyword">@import</span> <span class="hljs-string">"./node_modules/flyonui/variants.css"</span>; <span class="hljs-comment">/* Needed for JS components */</span>
<span class="hljs-keyword">@source</span> <span class="hljs-string">"./node_modules/flyonui/dist/index.js"</span>; <span class="hljs-comment">/* Needed for JS components */</span>
</code></pre>
<ul>
<li><p><code>@plugin "flyonui"</code> injects FlyonUI’s semantic classes into your build.</p>
</li>
<li><p>The <code>@import</code> includes custom variants created for the JS Components.</p>
</li>
<li><p>The <code>@source</code> line is required for the classes used in the js gets generated.</p>
</li>
</ul>
<h3 id="heading-3-include-flyonui-javascript-for-interactivity">3. <strong>Include FlyonUI JavaScript for Interactivity</strong></h3>
<p>Right before closing the <code>&lt;/body&gt;</code> tag in your HTML, include:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"../node_modules/flyonui/flyonui.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>This script enables the interactive behaviors for FlyonUI components, such as overlays, modals, and dropdowns.</p>
<h3 id="heading-4-use-a-flyonui-component">4. <strong>Use a FlyonUI Component</strong></h3>
<p>For example, update your UI with:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex items-center justify-center h-screen bg-gray-100"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary"</span>&gt;</span>
    Hello FlyonUI
  <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754374843709/41f9d3e3-d0be-4a32-a569-ce0618bea0e9.png" alt="41f9d3e3-d0be-4a32-a569-ce0618bea0e9" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<ul>
<li>The <code>.btn</code> and <code>.btn-primary</code> classes come from FlyonUI—giving you styled, semantic components without crafting custom CSS.</li>
</ul>
<h3 id="heading-why-it-matters"><strong>Why It Matters</strong></h3>
<ul>
<li><p><strong>Cleaner Code</strong>: FlyonUI’s semantic classes make your templates more readable and maintainable compared to verbose utility classes.</p>
</li>
<li><p><strong>Interactive Without the Overhead</strong>: Easily add dynamic features like modals or accordions through FlyonUI’s JS plugins—no need to code them from scratch.</p>
</li>
<li><p><strong>Effortless Styling</strong>: FlyonUI builds on Tailwind’s utility approach, so you can customize components with familiar classes instantly.</p>
</li>
</ul>
<h2 id="heading-lets-test-flyonui-js-components">Let’s Test FlyonUI JS Components</h2>
<p>To show how FlyonUI works, we’ll test one of its JavaScript-powered UI components, the <strong>Modal</strong>. Modals are common UI elements that grab user attention for alerts, confirmations, or extra information without moving away from the current page.</p>
<h3 id="heading-why-test-the-modal">Why Test the Modal?</h3>
<p>Testing the modal helps you:</p>
<ul>
<li><p>Check that FlyonUI’s JavaScript components load and work properly within your Electron and Tailwind setup.</p>
</li>
<li><p>See how simple it is to add interactive features using FlyonUI’s built-in classes and data attributes.</p>
</li>
<li><p>Understand how the modal responds to different screen sizes and how the UI reacts to user actions like opening and closing dialogs.</p>
</li>
</ul>
<h3 id="heading-how-to-test-the-modal">How to Test the Modal</h3>
<p>Copy the following example code into your <code>index.html</code> file. This button will open a modal dialog with some placeholder content:</p>
<p>We’ll use this <a target="_blank" href="https://flyonui.com/docs/overlays/modal/"><strong>Modal example</strong></a> for testing. Copy the following code in your <code>index.html</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary"</span> <span class="hljs-attr">aria-haspopup</span>=<span class="hljs-string">"dialog"</span> <span class="hljs-attr">aria-expanded</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">aria-controls</span>=<span class="hljs-string">"basic-modal"</span> <span class="hljs-attr">data-overlay</span>=<span class="hljs-string">"#basic-modal"</span>&gt;</span>Open modal<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"basic-modal"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"overlay modal overlay-open:opacity-100 hidden overlay-open:duration-300"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"dialog"</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"-1"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-dialog"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-content"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-header"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-title"</span>&gt;</span>Dialog Title<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-text btn-circle btn-sm absolute end-3 top-3"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Close"</span> <span class="hljs-attr">data-overlay</span>=<span class="hljs-string">"#basic-modal"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"icon-[tabler--x] size-4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-body"</span>&gt;</span>
        This is some placeholder content to show the scrolling behavior for modals. Instead of repeating the text in the
        modal, we use an inline style to set a minimum height, thereby extending the length of the overall modal and
        demonstrating the overflow scrolling. When content becomes longer than the height of the viewport, scrolling
        will move the modal as needed.
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-footer"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-soft btn-secondary"</span> <span class="hljs-attr">data-overlay</span>=<span class="hljs-string">"#basic-modal"</span>&gt;</span>Close<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary"</span>&gt;</span>Save changes<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>After updating the file, restart your Electron app:</p>
<pre><code class="lang-html">npm start
</code></pre>
<p>Here’s the result:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754374899394/4f153f2b-ca41-495f-b27e-18a2424a1952.png" alt="final result" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>You can use Tailwind CSS and Electron to build desktop applications that look good and operate well on different devices. This adds to Electron's many functions and Tailwind's good styling system, letting you stay productive and utilize clean design methods.</p>
<p>The full code and more details are in the repository here: <a target="_blank" href="https://github.com/themeselection/ts-electron-tailwind">ts-electron-tailwindcss</a>.</p>
<p>I have written this tutorial with the help of <a target="_blank" href="https://github.com/PruthviPraj00">Pruthvi Prajapati</a>, an experienced Tailwind CSS developer.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up Google Authentication in Laravel Applications ]]>
                </title>
                <description>
                    <![CDATA[ In this digital world, it’s important for your applications to have a smooth and secure authentication process. This helps improve user experience and the overall security of your apps. Google Authentication is among the most trusted and convenient w... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-up-google-auth-in-laravel-apps/</link>
                <guid isPermaLink="false">674f227adf280a40b7047b7f</guid>
                
                    <category>
                        <![CDATA[ Laravel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google authenticator ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google auth ]]>
                    </category>
                
                    <category>
                        <![CDATA[ socialite  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abhijeet Dave ]]>
                </dc:creator>
                <pubDate>Tue, 03 Dec 2024 15:23:38 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1732711351776/931a1ade-e652-4a0b-a16e-925482128fc0.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this digital world, it’s important for your applications to have a smooth and secure authentication process. This helps improve user experience and the overall security of your apps.</p>
<p>Google Authentication is among the most trusted and convenient ways for users to log into a site using their Google account. And it means that they don’t have to remember yet another username and password.</p>
<p>Integrating Google OAuth into your <a target="_blank" href="https://laravel.com/">Laravel</a> application simplifies the login process, encourages user engagement, and boosts the credibility of your platform. In this tutorial, I’ll guide you through the steps of implementing Google Authentication in a Laravel application. We’ll go from setting up the Google API credentials to configuring Laravel’s Socialite package.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-benefits-of-using-google-auth-in-a-laravel-app">Benefits of Using Google Auth in a Laravel App</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-laravel-google-login">How to Set Up Laravel Google Login</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>Before you begin, make sure you have the following prerequisites:</p>
<ol>
<li><p>Laravel 11</p>
</li>
<li><p>A Google Developer account.</p>
</li>
<li><p>Basic knowledge of Laravel and authentication.</p>
</li>
<li><p>Composer for managing packages</p>
</li>
</ol>
<p>Once you have these prerequisites ready, you’re all set to dive into integrating Google Authentication into your Laravel app.</p>
<h3 id="heading-benefits-of-using-google-auth-in-a-laravel-app">Benefits of Using Google Auth in a Laravel App</h3>
<p>There are many benefits to this set up. A few of them are:</p>
<ul>
<li><p>Simplified integration with Socialite</p>
</li>
<li><p>Seamless user authentication</p>
</li>
<li><p>Improved security</p>
</li>
<li><p>Customizable user flow</p>
</li>
<li><p>Improved scalability</p>
</li>
<li><p>Solid ecosystem support</p>
</li>
<li><p>Easier maintenance</p>
</li>
</ul>
<h2 id="heading-how-to-set-up-laravel-google-login">How to Set Up Laravel Google Login</h2>
<p>Whether you’re working on a personal project or a production-ready application, following these steps will help you smoothly integrate Google Authentication. Let’s get started.</p>
<h3 id="heading-step-1-set-up-a-google-cloud-project">Step 1: Set up a Google Cloud project</h3>
<p>To use Google Authentication in your Laravel application, first you need to configure a Google Cloud project. Follow these steps to set up your project:</p>
<ol>
<li><p>Visit the <a target="_blank" href="https://console.cloud.google.com/">Google Cloud console</a> and log in with your Google account.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733208476305/836ff373-152a-4b99-93f3-c7684591e5c7.png" alt="Laravel auth step 1" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
</li>
<li><p>Click on the <strong>“Select a Project”</strong> dropdown in the top navigation bar. In the popup, click on <strong>“New Project”</strong> to create a new project and provide the requested details. Then click on <strong>Create project</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733208488866/409092b9-20b5-4888-9c15-f22eff4226c8.png" alt="Laravel auth create project" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
</li>
<li><p>Once you create the project, open the console’s left side menu and select <strong>APIs &amp; Services &gt; Credentials</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733208517526/9b7df08c-8e8f-4db4-b297-a3f320edd0f0.png" alt="APIs &amp; Credentials" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
</li>
<li><p>On the Credentials page, click <strong>Create Credentials</strong> &gt; <strong>OAuth Client ID</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733208549370/6dcd64f1-1fe4-4a8b-b37e-f74b38bd694a.png" alt="OAuth Client ID" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
</li>
<li><p>If this is your first time creating a client ID, it will ask you to configure the consent screen. You can configure your consent screen by clicking <strong>Configure</strong> <strong>Consent Screen</strong>. If you have already configured the consent screen, you can skip this step.</p>
<ul>
<li><p>Select <strong>External</strong> if your app is for public use, or <strong>Internal</strong> if it’s limited to users within your Google Workspace organization.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733208660871/53aaf9a2-74d4-4cca-b4e5-9c5cfa9b3066.png" alt="OAuth consent" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
</li>
<li><p>Fill out the required details, like the <strong>app name</strong>, <strong>user support email</strong>, and any branding information. Click <strong>Save and Continue</strong>.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733208766209/4f458336-9a2a-4238-af89-de954ed2bcf4.png" alt="OAuth Consent Screen" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
</li>
</ul>
</li>
</ol>
<p>    After configuring the consent screen, return to the <strong>Credentials</strong> page and select <strong>OAuth Client ID</strong> again.</p>
<ol start="6">
<li><p>Choose the <strong>Application Type</strong> as <strong>Web Application</strong> and provide a name for client credentials (for example, Laravel Social Login).</p>
</li>
<li><p>Under <strong>Authorized Redirect URIs</strong>, add the callback URL for your application:</p>
<ul>
<li><p>Example: <code>http://your-app-url.com/callback/google</code></p>
</li>
<li><p>If you're testing locally, use: <a target="_blank" href="http://127.0.0.1:8000/api/auth/google/callback">http://127.0.0.1:8000/api/auth/google/callback</a></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733208840271/b7c309bc-4880-481b-acda-c0fecf4a0ee5.png" alt="OAuth client ID" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
</li>
</ul>
</li>
<li><p>Click on <strong>Create</strong>, and Google will generate a <strong>Client ID</strong> and <strong>Client Secret</strong> for your project. Save these credentials, as they will be required in the next steps.</p>
</li>
</ol>
<h3 id="heading-step-2-create-a-new-laravel-project-and-install-the-laravel-socialite-package">Step 2: Create a new Laravel project and Install the Laravel Socialite package</h3>
<p>If you don’t have one ready, you can create a new Laravel project using the below command:</p>
<pre><code class="lang-bash">composer create-project --prefer-dist laravel/laravel social-auth-example
</code></pre>
<p>To integrate Google Authentication into a Laravel project, we’ll use <a target="_blank" href="https://laravel.com/docs/11.x/socialite">Laravel Socialite</a>. Socialite is a first-party Laravel package that simplifies OAuth authentication with popular services like Google, Facebook, Twitter, and more.</p>
<p>To install Socialite, open your terminal in the root directory of your Laravel project and run the following command:</p>
<pre><code class="lang-bash">composer require laravel/socialite
</code></pre>
<h3 id="heading-step-3-configure-environment-variables">Step 3: Configure environment variables</h3>
<p>In this step, we will configure our Laravel application to use the Google OAuth credentials that we collected in Step 1.</p>
<p>Locate your <code>.env</code> file in the root directory of your project and add the following environment variables:</p>
<pre><code class="lang-tsx">GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URL=http://your-domain.com/auth/google/callback
</code></pre>
<p>Go ahead and replace all placeholders with secrets.</p>
<p>Let's understand each environment variable one by one:</p>
<ul>
<li><p><code>GOOGLE_CLIENT_ID</code>: A unique identifier for your app, provided by Google.</p>
</li>
<li><p><code>GOOGLE_CLIENT_SECRET</code>: A private key used by your app to authenticate itself securely with Google’s API.</p>
</li>
<li><p><code>GOOGLE_REDIRECT_URL</code>: The URL where Google redirects users after they log in. This should match the redirect URI you specified when creating the credentials in Step 1.</p>
</li>
</ul>
<h3 id="heading-step-4-update-the-config-files">Step 4: Update the config files</h3>
<p>To enable Laravel Socialite to use Google OAuth credentials, we need to configure the provider details in the <code>config/services.php</code> file.</p>
<p>In the <code>services.php</code> file, add the following configuration for the Google provider:</p>
<pre><code class="lang-php"><span class="hljs-string">'google'</span> =&gt; [
    <span class="hljs-string">'client_id'</span> =&gt; env(<span class="hljs-string">'GOOGLE_CLIENT_ID'</span>),        <span class="hljs-comment">// Your Google Client ID</span>
    <span class="hljs-string">'client_secret'</span> =&gt; env(<span class="hljs-string">'GOOGLE_CLIENT_SECRET'</span>), <span class="hljs-comment">// Your Google Client Secret</span>
    <span class="hljs-string">'redirect'</span> =&gt; env(<span class="hljs-string">'GOOGLE_REDIRECT_URL'</span>),      <span class="hljs-comment">// Your Google Redirect URL</span>
]
</code></pre>
<h3 id="heading-step-5-create-controllers-and-routes-for-authentication">Step 5: Create controllers and routes for authentication.</h3>
<p>In this step, we will create a controller to handle Google OAuth redirection and callbacks and set up the necessary routes to trigger these methods.</p>
<p>Run the following Artisan command to generate the <code>GoogleAuthController</code> controller:</p>
<pre><code class="lang-php">php artisan make:controller GoogleAuthController
</code></pre>
<p>This will create a controller at <code>app/Http/Controllers/GoogleAuthController.php</code>.</p>
<p>Replace the contents of the newly created <code>GoogleAuthController.php</code> with the following code:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\\<span class="hljs-title">Http</span>\\<span class="hljs-title">Controllers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\\<span class="hljs-title">Http</span>\\<span class="hljs-title">Controllers</span>\\<span class="hljs-title">Controller</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\\<span class="hljs-title">Models</span>\\<span class="hljs-title">User</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Laravel</span>\\<span class="hljs-title">Socialite</span>\\<span class="hljs-title">Facades</span>\\<span class="hljs-title">Socialite</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\\<span class="hljs-title">Support</span>\\<span class="hljs-title">Facades</span>\\<span class="hljs-title">Auth</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\\<span class="hljs-title">Support</span>\\<span class="hljs-title">Str</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Throwable</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GoogleAuthController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{
    <span class="hljs-comment">/**
     * Redirect the user to Google’s OAuth page.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">redirect</span>(<span class="hljs-params"></span>)
    </span>{
        <span class="hljs-keyword">return</span> Socialite::driver(<span class="hljs-string">'google'</span>)-&gt;redirect();
    }

    <span class="hljs-comment">/**
     * Handle the callback from Google.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callback</span>(<span class="hljs-params"></span>)
    </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-comment">// Get the user information from Google</span>
            $user = Socialite::driver(<span class="hljs-string">'google'</span>)-&gt;user();
        } <span class="hljs-keyword">catch</span> (<span class="hljs-built_in">Throwable</span> $e) {
            <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">'/'</span>)-&gt;with(<span class="hljs-string">'error'</span>, <span class="hljs-string">'Google authentication failed.'</span>);
        }

        <span class="hljs-comment">// Check if the user already exists in the database</span>
        $existingUser = User::where(<span class="hljs-string">'email'</span>, $user-&gt;email)-&gt;first();

        <span class="hljs-keyword">if</span> ($existingUser) {
            <span class="hljs-comment">// Log the user in if they already exist</span>
            Auth::login($existingUser);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// Otherwise, create a new user and log them in</span>
            $newUser = User::updateOrCreate([
                <span class="hljs-string">'email'</span> =&gt; $user-&gt;email
            ], [
                <span class="hljs-string">'name'</span> =&gt; $user-&gt;name,
                <span class="hljs-string">'password'</span> =&gt; bcrypt(Str::random(<span class="hljs-number">16</span>)), <span class="hljs-comment">// Set a random password</span>
                <span class="hljs-string">'email_verified_at'</span> =&gt; now()
            ]);
            Auth::login($newUser);
        }

        <span class="hljs-comment">// Redirect the user to the dashboard or any other secure page</span>
        <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">'/dashboard'</span>);
    }
}
</code></pre>
<p>This controller contains two functions:</p>
<ol>
<li><p>Redirect: Redirects the user to Google’s OAuth Page.</p>
</li>
<li><p>Callback: Handles the callback from Google and redirects the user to the dashboard or any other secure page.</p>
</li>
</ol>
<p>Let’s define the routes of <code>redirect</code> and <code>callback</code> in the <code>routes/web.php</code> file:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\\<span class="hljs-title">Http</span>\\<span class="hljs-title">Controllers</span>\\<span class="hljs-title">GoogleAuthController</span>;

<span class="hljs-comment">// Route to redirect to Google's OAuth page</span>
Route::get(<span class="hljs-string">'/auth/google/redirect'</span>, [GoogleAuthController::class, <span class="hljs-string">'redirect'</span>])-&gt;name(<span class="hljs-string">'auth.google.redirect'</span>);

<span class="hljs-comment">// Route to handle the callback from Google</span>
Route::get(<span class="hljs-string">'/auth/google/callback'</span>, [GoogleAuthController::class, <span class="hljs-string">'callback'</span>])-&gt;name(<span class="hljs-string">'auth.google.callback'</span>);
</code></pre>
<h3 id="heading-step-6-test-laravel-google-authentication-in-your-project">Step 6: Test Laravel Google authentication in your project.</h3>
<p>We’ve set up Google authentication, so now it’s time to test it to make sure it works seamlessly. In this step, we’ll use a login button that redirects the user to Google’s authentication page and returns them to a protected route upon successful login.</p>
<p>First, we will add the following button that gives users the option to Login With Google:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ route('auth.google.redirect') }}"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn bg-blue-100 p-3 shadow-sm border rounded-md text-blue-900"</span>&gt;</span>
    Login with Google 
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<p>For testing purposes, I have defined a protected route and a <code>dashboard</code>. This route will only be accessible to authenticated users. After logging in, we will redirect users to this page. Let’s define this route in <code>web.php</code>:</p>
<pre><code class="lang-php">Route::get(<span class="hljs-string">'/dashboard'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> view(<span class="hljs-string">'dashboard'</span>);
})-&gt;middleware(<span class="hljs-string">'auth'</span>)-&gt;name(<span class="hljs-string">'dashboard'</span>);
</code></pre>
<p>Next, create a blade view file for the dashboard at <code>resources/views/dashboard.blade.php</code>. Here’s the contents of the dashboard:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Dashboard<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Dashboard<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Welcome to the dashboard, {{ auth()-&gt;user()-&gt;name }}!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Here, we’re using the <code>auth()-&gt;user()</code> helper to display the logged-in user’s name, which is fetched from the Google account they used to sign in.</p>
<p>Now, Let’s try to log in.</p>
<p>This is the login page:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732703980184/ecc90d0d-142b-43fe-8457-1b84a54f62d3.png" alt="Login screen - &quot;Login with Google&quot;" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Clicking on the button will redirect you to Google’s consent screen:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732703936372/59f4a5bf-907d-4dda-ba8b-6909cf0a4376.png" alt="Laravel Google auth example - consent screen" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Click on the continue, and you should be logged in to the app. You will be redirected to a screen like below. You can see the welcome message with the user’s name.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732703886846/17ab7939-34c1-4d82-9527-99afb78cf3eb.png" alt="Laravel auth example - welcome screen" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>That’s it! You’ve successfully implemented and tested Google Authentication in your Laravel project. Now your users can sign in using their Google accounts, enhancing both security and convenience.</p>
<p>To refer to the full implementation, you can find the complete source code for this project on GitHub here: <a target="_blank" href="https://github.com/DeepKumbhare85/social-auth-example"><strong>Google Login Integration for Laravel</strong> - GitHub Repository</a></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You’ve now set up Google authentication in your Laravel application using Socialite! You can extend this method to include other OAuth providers like Facebook, Twitter, or GitHub by adding additional configurations to the <code>config/services.php</code> file.</p>
<p>Google OAuth integration is a common feature for modern web applications, and Laravel Socialite makes it easy to implement.</p>
<p>In case you need more social login options like GitHub, Twitter, and Facebook, then you can consider ready-to-use Laravel SaaS boilerplates.</p>
<p>Most of the pre-built Laravel SaaS boilerplates offer seamless integration with popular platforms such as Google, GitHub, Facebook, and Twitter. For example, there are some premium and open source resources like:</p>
<ul>
<li><p><a target="_blank" href="https://demos.themeselection.com/jetship-laravel-starter-kit/">Laravel Starter Kit</a> (Premium)</p>
<ul>
<li><p>Based on Tailwind CSS</p>
</li>
<li><p>Comes with One Click Magic Link Setup</p>
</li>
<li><p>Supports various authentication methods including the traditional email/password login</p>
</li>
<li><p>2FA Authentication</p>
</li>
</ul>
</li>
<li><p><a target="_blank" href="https://github.com/miracuthbert/saas-boilerplate">SaaS Boilerplate</a> (Open Source)</p>
<ul>
<li><p>Single Database Multi-tenancy</p>
</li>
<li><p>Developer Panel</p>
</li>
<li><p>Manage Personal Access Tokens</p>
</li>
</ul>
</li>
<li><p><a target="_blank" href="https://github.com/fumeapp/laranuxt">Laranuxt</a> (Open Source)</p>
<ul>
<li><p>Nuxt UI a collection of components built by the NuxtJS team, powered by Tailwind CSS</p>
</li>
<li><p>Authentication library to assist with user sessions and logging in/out</p>
</li>
<li><p>Example Authentication Middleware</p>
</li>
</ul>
</li>
<li><p><a target="_blank" href="https://github.com/alefesouza/laravel-vue-boilerplate">Laravel Vue Boilerplate</a> (Open Source)</p>
<ul>
<li><p>WebSockets with Laravel Echo and Pusher.</p>
</li>
<li><p>Workbox for better PWA development.</p>
</li>
<li><p>Laravel GraphQL</p>
</li>
</ul>
</li>
</ul>
<p>Using one of these Laravel SaaS boilerplates can speed up your workflows as you don’t need to set up everything from scratch.</p>
<p>Special thanks to <a target="_blank" href="https://github.com/DeepKumbhare85">Deep Kumbhare</a>, an experienced Laravel Developer and enthusiast, who has helped me with preparing this article.</p>
<p>I hope this article helps you with setting up Google Login with Laravel.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Integrate Tailwind with Django – With Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ In modern web development, choosing the right technology is crucial because it impacts both the process and outcome of your projects. Using Django as a backend framework and Tailwind CSS as a utility-first CSS framework offers an efficient way to cre... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-integrate-tailwind-with-django/</link>
                <guid isPermaLink="false">672a2317dd9236b285ebb527</guid>
                
                    <category>
                        <![CDATA[ tailwind ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Django ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abhijeet Dave ]]>
                </dc:creator>
                <pubDate>Tue, 05 Nov 2024 13:52:23 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730270888412/a440ff74-6e8b-4879-8b47-15aedca45bc4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In modern web development, choosing the right technology is crucial because it impacts both the process and outcome of your projects. Using Django as a backend framework and Tailwind CSS as a utility-first CSS framework offers an efficient way to create responsive and visually appealing web applications.</p>
<p>This article will explain why Django and Tailwind CSS work well together, how to start a Django project, how to easily add Tailwind CSS, and how to speed up your development with Prettier for better class formatting.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-a-quick-overview-of-django">A Quick Overview of Django</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-tailwind-css">What is Tailwind CSS?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-django-and-tailwind-work-so-well-together">Why Django and Tailwind Work So Well Together?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-initialize-a-django-project">How to Initialize a Django Project?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-integrate-tailwind-css-with-django">How to Integrate Tailwind CSS with Django?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-lets-create-a-chat-bubble-app">Let’s Create a Chat Bubble app.</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-prettier-for-class-formatting">How to Use Prettier for Class Formatting?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-chat-bubble-using-flyonui-tailwind-components-and-django">How to Create a Chat Bubble Using FlyonUI Tailwind Components and Django</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-a-quick-overview-of-django">A Quick Overview of Django</h2>
<p><a target="_blank" href="https://www.djangoproject.com/">Django</a> is an open-source, full-featured Python web framework that follows the batteries-included approach. Django aims at making the development of complex, database-driven websites as fast and easy as possible by providing a lot of built-in functionalities like ORM, authentication system, admin panel, and many more. Django enables rapid development by focusing on writing the app's unique parts rather than wasting time writing a lot of boilerplate code.</p>
<p>The reason for its popularity is that it follows the MVT design pattern which keeps data models, views, and templates well separated. In Django, security is paramount: it guards against SQL injection, cross-site scripting, and cross-site request forgery out of the box. Django scales well and is flexible – it is fit for both small projects and large, complex web applications, and that is why it is used by major sites such as Instagram and Pinterest.</p>
<h2 id="heading-what-is-tailwind-css">What is Tailwind CSS?</h2>
<p>It is a well-known fact that <a target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a> is a utility-first CSS framework. It lets you style elements directly within your HTML, thanks to pre-defined classes. Unlike other CSS frameworks that offer pre-built components, Tailwind offers these low-level utility classes that let you create your own design system. Thus, this makes crafting unique responsive designs effortless as there is not much to do with custom CSS.</p>
<h2 id="heading-why-django-and-tailwind-work-so-well-together">Why Django and Tailwind Work So Well Together?</h2>
<p>The combination of Django and Tailwind CSS offers a seamless way to build robust, full-featured applications. Here’s why:</p>
<ul>
<li><p><strong>Rapid Development</strong>: Django’s backend capabilities allow developers to create powerful applications quickly, while Tailwind CSS helps streamline the styling process with its utility-first approach.</p>
</li>
<li><p><strong>Customizable Design</strong>: With Tailwind, you’re not confined to predefined styles. You can craft a unique, consistent design that scales easily as your project grows.</p>
</li>
<li><p><strong>Separation of Concerns</strong>: Django’s templating system works hand-in-hand with Tailwind CSS, ensuring a clear separation between the backend logic and frontend styling.</p>
</li>
</ul>
<h2 id="heading-how-to-initialize-a-django-project">How to Initialize a Django Project?</h2>
<ol>
<li><p><strong>Install Django</strong>: Install Django using pip:</p>
<pre><code class="lang-bash"> pip install django
</code></pre>
</li>
<li><p><strong>Create a Django Project</strong>: Use the Django admin command to create a new project:</p>
<pre><code class="lang-bash"> django-admin startproject myproject
</code></pre>
</li>
<li><p><strong>Navigate to Your Project Directory</strong>:</p>
<pre><code class="lang-bash"> <span class="hljs-built_in">cd</span> myproject
</code></pre>
</li>
<li><p><strong>Modify</strong> <code>settings.py</code>:</p>
<ul>
<li><p>In the <code>TEMPLATES</code> setting, add a <code>templates</code> directory:</p>
<pre><code class="lang-python">  <span class="hljs-string">"DIRS"</span>: [BASE_DIR / <span class="hljs-string">"templates"</span>],
</code></pre>
</li>
<li><p>Add a <code>static</code> directory for your static files:</p>
<pre><code class="lang-python">  STATICFILES_DIRS = [BASE_DIR / <span class="hljs-string">"static"</span>]
</code></pre>
</li>
</ul>
</li>
</ol>
<h2 id="heading-how-to-integrate-tailwind-css-with-django">How to Integrate Tailwind CSS with Django?</h2>
<ol>
<li><p><strong>Install Tailwind CSS</strong>: Make sure Node.js is installed, then run:</p>
<pre><code class="lang-bash"> npm install -D tailwindcss
 npx tailwindcss init
</code></pre>
</li>
<li><p><strong>Set Up Tailwind CSS</strong>: In your <code>static/css</code> directory, create a <code>main.css</code> file with the following content:</p>
<pre><code class="lang-css"> <span class="hljs-keyword">@tailwind</span> base;
 <span class="hljs-keyword">@tailwind</span> components;
 <span class="hljs-keyword">@tailwind</span> utilities;
</code></pre>
</li>
<li><p><strong>Modify tailwind.config.js</strong>: Adjust the content section to include <code>templates/*.html</code> files, ensuring Tailwind CSS generates the necessary styles.</p>
<pre><code class="lang-jsx"> <span class="hljs-comment">/** <span class="hljs-doctag">@type <span class="hljs-type">{import('tailwindcss').Config}</span> </span>*/</span>
 <span class="hljs-built_in">module</span>.exports = {
     <span class="hljs-attr">content</span>: [<span class="hljs-string">"./templates/**/*.html"</span>, <span class="hljs-string">"./**/templates/**/*.html"</span>],
     <span class="hljs-attr">darkMode</span>: <span class="hljs-string">"media"</span>,
     <span class="hljs-attr">theme</span>: {
         <span class="hljs-attr">extend</span>: {},
     },
     <span class="hljs-attr">plugins</span>: [],
 };
</code></pre>
</li>
<li><p><strong>Add a Build Script</strong>: Update your <code>package.json</code> to include a build script:</p>
<pre><code class="lang-json"> <span class="hljs-string">"scripts"</span>: {  <span class="hljs-attr">"watch:css"</span>: <span class="hljs-string">"tailwindcss build static/css/main.css -o static/output.css -w"</span>}
</code></pre>
</li>
<li><p><strong>Compile Tailwind CSS</strong>:</p>
<pre><code class="lang-bash"> npm run watch:css
</code></pre>
</li>
</ol>
<h2 id="heading-lets-create-a-chat-bubble-app">Let’s Create a Chat Bubble app.</h2>
<ol>
<li><p><strong>Create a Django App</strong>:</p>
<pre><code class="lang-bash"> django-admin startapp chat
</code></pre>
</li>
<li><p><strong>Set Up the Views</strong>:</p>
<ul>
<li><p>In <code>chat/views.py</code>, create a simple view:</p>
<pre><code class="lang-python">  <span class="hljs-keyword">from</span> django.shortcuts <span class="hljs-keyword">import</span> render
  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">chat</span>(<span class="hljs-params">request</span>):</span>
      <span class="hljs-keyword">return</span> render(request, <span class="hljs-string">"chat.html"</span>)
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Configure URLs</strong>:</p>
<ul>
<li><p>In <code>chat/urls.py</code>, define the URL pattern for your view:</p>
<pre><code class="lang-python">  <span class="hljs-keyword">from</span> django.urls <span class="hljs-keyword">import</span> path
  <span class="hljs-keyword">from</span> . <span class="hljs-keyword">import</span> views
  urlpatterns = [
      path(<span class="hljs-string">""</span>, views.chat, name=<span class="hljs-string">"chat"</span>),
  ]
</code></pre>
</li>
<li><p>In the project’s <code>urls.py</code>, include the app URLs:</p>
<pre><code class="lang-python">  <span class="hljs-keyword">from</span> django.urls <span class="hljs-keyword">import</span> include, path
  urlpatterns = [
      path(<span class="hljs-string">""</span>, include(<span class="hljs-string">"chat.urls"</span>)),
  ]
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Set Up the Base HTML Template</strong>:</p>
<ul>
<li><p>Create a <code>templates/base.html</code> file to serve as the foundation of your application:</p>
<pre><code class="lang-html">  {% load static %}

  <span class="hljs-meta">&lt;!doctype <span class="hljs-meta-keyword">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>My Django App with Tailwind<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{% static 'css/output.css' %}"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"h-screen bg-slate-300 dark:bg-slate-400"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container mx-auto flex flex-col items-center"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mb-4 mt-10 text-6xl font-bold text-blue-500 dark:text-blue-200"</span> &gt;</span>
          Chat Bubble
        <span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        {% block content %} {% endblock %}
      <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Create the Chat Template</strong>:</p>
<ul>
<li>In <code>templates/chat.html</code>, extend the base template:</li>
</ul>
</li>
</ol>
<pre><code class="lang-html">    {% extends "base.html" %}

    {% block content %}
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex items-start gap-2.5"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-8 h-8 rounded-full"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"&lt;https://cdn.flyonui.com/fy-assets/avatar/avatar-1.png&gt;"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Jhon  image"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex flex-col gap-1 w-full max-w-[320px]"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex items-center space-x-2 rtl:space-x-reverse"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-sm font-semibold text-gray-900 dark:text-white"</span>&gt;</span>Jhon Doe<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-sm font-normal text-gray-500 dark:text-gray-400"</span>&gt;</span>11:46<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
                <span class="hljs-attr">class</span>=<span class="hljs-string">"flex flex-col leading-1.5 p-4 border-gray-200 bg-gray-100 rounded-e-xl rounded-es-xl dark:bg-gray-700"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-sm font-normal text-gray-900 dark:text-white"</span>&gt;</span> That's awesome. I think our users will really
                    appreciate the improvements.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-sm font-normal text-gray-500 dark:text-gray-400"</span>&gt;</span>Delivered<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    {% endblock %}
</code></pre>
<ol start="6">
<li><strong>Run the Development Server</strong>: <code>bash python manage.py runserver</code></li>
</ol>
<h2 id="heading-how-to-use-prettier-for-class-formatting">How to Use Prettier for Class Formatting?</h2>
<p>To keep your Tailwind CSS classes clean and organized, you can integrate Prettier into your workflow.</p>
<ol>
<li><p><strong>Install Prettier and the Tailwind Plugin</strong>:</p>
<pre><code class="lang-bash"> npm install --save-dev prettier prettier-plugin-tailwindcss
</code></pre>
</li>
<li><p><strong>Configure Prettier</strong>: Create a <code>.prettierrc</code> file in your project root:</p>
<pre><code class="lang-json"> {  <span class="hljs-attr">"plugins"</span>: [<span class="hljs-string">"prettier-plugin-tailwindcss"</span>]}
</code></pre>
</li>
<li><p><strong>Format on Save</strong>: Set up your code editor to format files automatically with Prettier on save.</p>
</li>
</ol>
<h3 id="heading-result">Result:</h3>
<p>GitHub Repo: <a target="_blank" href="https://github.com/themeselection/ts-django-tailwind">ts-django-tailwindcss</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730793420930/6fbdbfbb-2476-4454-9b90-89bcfd405abf.png" alt="chat bubble ts" class="image--center mx-auto" width="503" height="278" loading="lazy"></p>
<h2 id="heading-how-to-create-a-chat-bubble-using-flyonui-tailwind-components-and-django">How to Create a Chat Bubble Using FlyonUI Tailwind Components and Django</h2>
<p>Here, we’ll use FlyonUI, an open-source <a target="_blank" href="https://flyonui.com/">Tailwind CSS Components Library</a>. It offers a wide range of customizable, accessible, and ready-to-use components.</p>
<p>Let’s integrate Django with FlyonUI components and create a chat bubble.</p>
<p><strong>Step 1: Install flyonui</strong></p>
<p>Install <code>flyonui</code> via npm.</p>
<pre><code class="lang-bash">npm install -D flyonui@latest
</code></pre>
<p><strong>Step 2: Configure Tailwind</strong></p>
<p>Add the path to FlyonUI JavaScript files in your <code>tailwind.config.js</code> file.</p>
<pre><code class="lang-plaintext">module.exports = {
  content: ["./node_modules/flyonui/dist/js/*.js"], // Require only if you want to use FlyonUI JS component

  plugins: [
    require("flyonui"),
    require("flyonui/plugin") // Require only if you want to use FlyonUI JS component
  ]
}
</code></pre>
<p><strong>Step 3: Copy the FlyonUI JavaScript</strong></p>
<p>Copy FlyonUI's JavaScript (node_modules/flyonui/flyonui.js) files to the <code>static/</code>  folder.</p>
<p><strong>Step 4: Add Js to your base.html</strong></p>
<p>Once you copied the <code>js file</code> to your static folder include it in base.html.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
 ...
 <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  ...
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"{% static 'js/flyonui.js' %}"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Let's Update the Chat bubble code block:</p>
<pre><code class="lang-html">{% extends "base.html" %}
{% block content %}
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chat chat-receiver"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"avatar chat-avatar"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"size-10 rounded-full"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span>
          <span class="hljs-attr">src</span>=<span class="hljs-string">"&lt;https://cdn.flyonui.com/fy-assets/avatar/avatar-1.png&gt;"</span>
          <span class="hljs-attr">alt</span>=<span class="hljs-string">"avatar"</span>
        /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chat-header text-base-content/90"</span>&gt;</span>
      Obi-Wan Kenobi
      <span class="hljs-tag">&lt;<span class="hljs-name">time</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-base-content/50"</span>&gt;</span>12:45<span class="hljs-tag">&lt;/<span class="hljs-name">time</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chat-bubble"</span>&gt;</span>I started learning guitar today!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chat-footer text-base-content/50"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Delivered<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chat chat-sender"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"avatar chat-avatar"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"size-10 rounded-full"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span>
          <span class="hljs-attr">src</span>=<span class="hljs-string">"&lt;https://cdn.flyonui.com/fy-assets/avatar/avatar-2.png&gt;"</span>
          <span class="hljs-attr">alt</span>=<span class="hljs-string">"avatar"</span>
        /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chat-header text-base-content/90"</span>&gt;</span>
      Anakin
      <span class="hljs-tag">&lt;<span class="hljs-name">time</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-base-content/50"</span>&gt;</span>12:46<span class="hljs-tag">&lt;/<span class="hljs-name">time</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chat-bubble"</span>&gt;</span>
      That's awesome! You're going to be great at it!
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chat-footer text-base-content/50"</span>&gt;</span>
      Seen
      <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"icon-[tabler--checks] align-bottom text-success"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
{% endblock %}
</code></pre>
<h3 id="heading-result-1"><strong>Result:</strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730793343310/63ca723e-ef67-4cee-a112-bed110ce8ea6.png" alt="chat bubble example" class="image--center mx-auto" width="700" height="334" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Using Tailwind CSS with Django is a great way to make your web applications look good and work well on different devices, while you take advantage of Django's many features. This setup not only boosts productivity but also helps you follow good styling and design practices.</p>
<p>Here's the repository where you can find more details or see the complete code: <a target="_blank" href="https://github.com/themeselection/ts-django-tailwind">ts-django-tailwindcss</a>. I hope this tutorial helps you with the Django integration with Tailwind CSS. I have prepared this article with the help of <a target="_blank" href="https://github.com/PruthviPraj00">Pruthvi Prajapati</a>, a front-end developer with 2 years of experience.</p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Vue E-commerce App Using MSW ]]>
                </title>
                <description>
                    <![CDATA[ Building an e-commerce app can be a time-consuming task, but with the right tools, it becomes much more manageable. In this guide, we'll explore how to create a robust Vue.js e-commerce application using Mock Service Worker (MSW) to simulate backend ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-vue-ecommerce-app-using-msw/</link>
                <guid isPermaLink="false">66bb55013c8a48be917afce0</guid>
                
                    <category>
                        <![CDATA[ ecommerce ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vue ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abhijeet Dave ]]>
                </dc:creator>
                <pubDate>Mon, 08 Jul 2024 18:49:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/07/build-a-Vue-eCommerce-App-using-MSW.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Building an e-commerce app can be a time-consuming task, but with the right tools, it becomes much more manageable. In this guide, we'll explore how to create a robust Vue.js e-commerce application using Mock Service Worker (MSW) to simulate backend interactions. </p>
<p>Whether you're a seasoned developer or just starting out, this step-by-step tutorial will help you understand the fundamentals of integrating MSW into your Vue project, enabling you to build and test your application more effectively without relying on a real backend. </p>
<p>Let's dive in and bring your e-commerce vision to life!</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a href="#what-is-a-mock-server">What is a Mock Server?</a></li>
<li><a href="#how-to-set-up-a-vue-e-commerce-app">How to Set Up a Vue E-commerce App</a></li>
<li><a href="#getting-started-with-vue-e-commerce-app">Getting Started With Vue E-commerce App</a></li>
<li><a href="#how-to-build-an-e-commerce-app-using-vue-3">How to Build an E-commerce App Using Vue 3</a></li>
<li><a href="#how-to-build-the-user-interface">How to Build the User Interface</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>

<p>In this article, we'll walk through the process of building an e-commerce app from scratch using <a target="_blank" href="https://vuejs.org/">Vue.js</a> and the power of MSW for mocking API calls.</p>
<p>Before we start with the project, let’s take an overview of the e-commerce pages that we are going to build for the app. It'll have mainly two pages:</p>
<ul>
<li>Shop page.</li>
<li>Product details page.</li>
</ul>
<p><strong>Shop page</strong>: This page will display all the products of the store.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/eCommerce-Products-Page.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mock-up created using Pika Style</em></p>
<p><strong>Product details page</strong>: This page displays all the details regarding the product.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/eCommerce-product-details-page.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Before building an e-commerce app, let’s clarify some basics about the mock server.</p>
<h2 id="heading-what-is-a-mock-server">What is a Mock Server?</h2>
<p>A mock server simply mimics a real server by providing predefined responses for an API request. A mock server is useful for testing and development as it can generate different test cases without risking the integrity of real data. You can configure a mock server to return specific responses, error messages and timeouts.</p>
<p>There are various tools/libraries out there that you can use to set up a mock server. In this article, we will use MSW (Mock Service Worker) to set up a mock server. You can learn more about MSW from its official <a target="_blank" href="https://mswjs.io/">documentation</a>.</p>
<p>Now, let’s set up a mock server (using MSW) for our Vue e-commerce app.</p>
<h2 id="heading-how-to-set-up-a-vue-e-commerce-app">How to Set Up a Vue E-commerce App</h2>
<p>For our e-commerce app, we'll need two API endpoints. Below is a brief description of API endpoints.</p>
<ol>
<li><code>/api/apps/ecommerce/products</code>: This will fetch the data of all products we have in store.</li>
<li><code>/api/apps/ecommerce/product/:id</code>: This will fetch the product details of a specific product by its ID.</li>
</ol>
<p>We'll use a free Vue admin dashboard that offers essential features such as:</p>
<ul>
<li>Beautifully crafted components</li>
<li>Auto import capabilities</li>
<li>Premade layout, and so on.</li>
</ul>
<p>These features will make it easier and faster to develop the Vue e-commerce app.</p>
<h2 id="heading-getting-started-with-vue-e-commerce-app">Getting Started With Vue E-commerce App</h2>
<p>There are plenty of <a target="_blank" href="https://vuejs.org/ecosystem/themes">Vue.js themes</a> available that you can consider for creating an e-commerce  app. </p>
<p>Here, we'll use the Materio Vue.js admin free template<em>.</em> First, go to the <a target="_blank" href="https://github.com/themeselection/materio-vuetify-vuejs-admin-template-free">GitHub repo</a>.</p>
<p>To clone it, simply open your terminal. Navigate to the directory where you would like to clone the project and run the following command:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> &lt;https://github.com/themeselection/materio-vuetify-vuejs-admin-template-free.git&gt;
</code></pre>
<p>Open the project in your favorite IDE and run the command below in the terminal to install all the dependencies. </p>
<p>We'll use the <a target="_blank" href="https://pnpm.io/"><code>pnpm</code></a> package manager as recommended by the dashboard we're using. However, you are free to use your preferred package manager like npm or yarn.</p>
<pre><code class="lang-bash">pnpm install
<span class="hljs-comment"># npm install</span>
<span class="hljs-comment"># yarn</span>
</code></pre>
<p>Next, install MSW in your project directory:</p>
<pre><code class="lang-bash">pnpm add -D msw@latest
<span class="hljs-comment"># npm install msw@latest --save-dev</span>
<span class="hljs-comment"># yarn install -D msw@latest</span>
</code></pre>
<p>Run the theme using the following command:</p>
<pre><code class="lang-bash">pnpm run dev
<span class="hljs-comment"># npm run dev</span>
<span class="hljs-comment"># yarn run dev</span>
</code></pre>
<p>Next, initialize MSW using the command below. Running this command will create a <strong>mockServiceWorker.js</strong> file in a public directory.</p>
<pre><code class="lang-bash">npx msw init public
</code></pre>
<p>To manage all API endpoints and fake data, create a new folder called <strong>fake-server</strong> inside the <strong>plugins</strong> directory. We’ll set up our mock server in this <strong>fake-server</strong> directory. Create an <strong>index.ts</strong> file and paste the below code to register <code>MSW</code>.</p>
<pre><code class="lang-tsx">// file: src/plugins/fake-server/index.ts

import { setupWorker } from 'msw/browser'

const worker = setupWorker()

export default function () {
  const workerUrl = `${import.meta.env.BASE_URL ?? '/'}mockServiceWorker.js`

  worker.start({
    serviceWorker: {
      url: workerUrl,
    },
    onUnhandledRequest: 'bypass',
  })
}
</code></pre>
<p>Congratulations, you have now successfully set up <code>MSW</code> in the project. Now, we can start building an e-commerce app.</p>
<h2 id="heading-how-to-build-an-e-commerce-app-using-vue-3">How to Build an E-commerce App Using Vue 3</h2>
<p>In the <strong>fake-server</strong> directory, create a <strong>handlers</strong> directory for maintaining handlers. Inside the <strong>handlers</strong> directory, create an <strong>ecommerce</strong> directory for the e-commerce app’s handlers. Then, create a <strong>db.ts</strong> file inside <strong>ecommerce</strong> to store the fake data.</p>
<p>Your folder structure should look like this:</p>
<pre><code class="lang-tsx">.
└── fake-server/
    └── handlers/
        └── ecommerce/
            └── db.ts
</code></pre>
<p>I have generated some fake data for displaying products. Let’s place this fake data in <strong>db.ts</strong>:</p>
<pre><code class="lang-tsx">// file: src/plugins/fake-server/handlers/ecommerce/db.ts

import product5 from '@images/eCommerce/1.png'
import product3 from '@images/eCommerce/11.png'
import product6 from '@images/eCommerce/18.png'
import product1 from '@images/eCommerce/27.png'
import product4 from '@images/eCommerce/5.png'
import product2 from '@images/eCommerce/7.png'

export const db = {
  products: [
    {
      id: 1,
      productName: 'Gaming Mouse',
      category: 'Electronics',
      price: '$999',
      image: product1,
      rating: 5,
      productDescription: 'A mouse specifically designed for gamers.',
    },
    {
      id: 2,
      productName: 'Google Home',
      category: 'Electronics',
      price: '$25.50',
      image: product2,
      rating: 4,
      productDescription: 'A Smart speaker with Google Assistant.',
    },
    {
      id: 3,
      productName: 'INZCOU Running Shoes',
      category: 'Shoes',
      price: '$36.98',
      image: product3,
      rating: 5,
      productDescription: 'Lightweight Tennis Shoes Non Slip Gym Workout Shoes',
    },
    {
      id: 4,
      productName: 'MacBook Pro 16',
      category: 'Electronics',
      price: '$2648.95',
      image: product4,
      rating: 5,
      productDescription: 'Laptop M2 Pro chip with 12‑core CPU and 19‑core GPU',
    },
    {
      id: 5,
      productName: 'Apple Watch Series 7',
      category: 'Office',
      price: '$799',
      image: product5,
      rating: 5,
      productDescription: 'Starlight Aluminum Case with Starlight Sport Band.',
    },
    {
      id: 6,
      productName: 'Meta Quest 2',
      category: 'Office',
      price: '$299',
      image: product6,
      rating: 5,
      productDescription: 'Advanced All-In-One Virtual Reality Headset',
    },
  ],
}
</code></pre>
<p>As discussed in this app structure, we need to define two endpoints. Create an <strong>index.ts</strong> file in your e-commerce handler and define your endpoints in it:</p>
<pre><code class="lang-tsx">// file: src/plugins/fake-server/handlers/ecommerce/index.ts

import { HttpResponse, http } from 'msw'
import { db } from './db'

export const handlerEcommerce = [
  http.get('/api/ecommerce/products', () =&gt; {
    const products = db.products

    return HttpResponse.json(products, { status: 200 })
  }),

  http.get('/api/ecommerce/products/:id', ({ params }) =&gt; {
    const id = Number(params.id)

    const product = db.products.find(item =&gt; item.id === id)

    if (!product)
      return HttpResponse.error()

    return HttpResponse.json(product, { status: 200 })
  }),
]
</code></pre>
<p>Register the handler in the <strong>index.ts</strong> file in the <strong>fake-server</strong> direrctory. The updated <strong>index.ts</strong> file should look like this:</p>
<pre><code class="lang-tsx">// file: src/plugins/fake-server/index.ts

import { setupWorker } from 'msw/browser'

import { handlerEcommerce } from './handlers/ecommerce'

const worker = setupWorker(...handlerEcommerce)

export default function () {
  const workerUrl = `${import.meta.env.BASE_URL ?? '/'}mockServiceWorker.js`

  worker.start({
    serviceWorker: {
      url: workerUrl,
    },
    onUnhandledRequest: 'bypass',
  })
}
</code></pre>
<p>The setup of the mock server has been completed. Whenever you make an API call to your endpoint, MSW will intercept the HTTP request using the service worker and will provide a predefined response from the handlers.</p>
<p>Congratulations, you have successfully set up the mock server👍.🏻</p>
<h2 id="heading-how-to-build-the-user-interface">How to Build the User Interface</h2>
<p>Let's move on to the UI part of the e-commerce app. Create an <strong>apps</strong> directory in the <strong>pages</strong> directory. Inside <strong>apps</strong>, create a new directory called <strong>ecommerce</strong>. We'll place the e-commerce app in this directory.</p>
<p>The folder structure should look like this:</p>
<pre><code class="lang-tsx">.
└── pages/
    └── apps/
        └── ecommerce
</code></pre>
<p>The first page is a product listing page. Create a new directory of <strong>products</strong> inside <strong>ecommerce</strong>. Create an <strong>index.vue</strong> file in the <strong>products</strong> directory and paste the following code snippet:</p>
<pre><code class="lang-tsx">// file: src/pages/apps/ecommerce/products/index.vue

&lt;script setup lang="ts"&gt;
const router = useRouter()
const { data: products } = await useFetch('/api/ecommerce/products').json()
&lt;/script&gt;

&lt;template&gt;
  &lt;div&gt;
    &lt;div class="d-flex flex-wrap gap-6 justify-center"&gt;
      &lt;template
        v-for="(product, index) in products"
        :key="index"
      &gt;
        &lt;VCard width="300"&gt;
          &lt;VImg
            :src="product.image"
            cover
          /&gt;
          &lt;VCardItem&gt;
            &lt;VCardTitle&gt;{{ product.productName }}&lt;/VCardTitle&gt;
            &lt;VCardSubtitle&gt;Price: {{ product.price }}&lt;/VCardSubtitle&gt;
          &lt;/VCardItem&gt;
          &lt;VCardText&gt;
            &lt;p class="mb-0"&gt;
              {{ product.productDescription }}
            &lt;/p&gt;
            &lt;VRating
              :model-value="product.rating"
              readonly
              density="compact"
              class="my-3"
            /&gt;
            &lt;VBtn
              block
              @click="() =&gt; router.push({ path: `/apps/ecommerce/products/${product.id}` })"
            &gt;
              Buy Now
            &lt;/VBtn&gt;
          &lt;/VCardText&gt;
        &lt;/VCard&gt;
      &lt;/template&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/template&gt;
</code></pre>
<p>In this product listing page, we made an API call to the <code>'/api/ecommerce/products'</code> endpoint. This endpoint returns the array of all products. We'll use this data to display products on the page.</p>
<p>The second page in this app is the product display page. On this page, we'll display all the details of the product. To do so, create a new file <strong>[id].vue</strong> inside the <strong>products</strong> directory. Below is the code for the product details page.</p>
<p>Note that I have used Lorem ipsum to keep it generic. You can replace it with your desired description. </p>
<pre><code class="lang-tsx">// file: src/pages/apps/ecommerce/products/[id].vue

&lt;script setup lang="ts"&gt;
const route = useRoute()
const router = useRouter()

const { data: product } = await useFetch(`/api/ecommerce/products/${route.params.id}`).json()
const quantity = ref(0)
&lt;/script&gt;

&lt;template&gt;
  &lt;VCard class="pa-10"&gt;
    &lt;VRow&gt;
      &lt;VCol
        md="4"
        cols="12"
      &gt;
        &lt;div class="py-10 bg-background d-flex justify-center"&gt;
          &lt;VImg
            :src="product.image"
            width="auto"
            max-height="40vh"
          /&gt;
        &lt;/div&gt;
      &lt;/VCol&gt;

      &lt;VCol
        md="8"
        cols="12"
      &gt;
        &lt;div&gt;
          &lt;div class="text-h3 mb-4"&gt;
            {{ product.productName }}
          &lt;/div&gt;

          &lt;div class="text-h4 mb-4"&gt;
            {{ product.price }}
          &lt;/div&gt;

          &lt;div&gt;
            &lt;p&gt;
              {{ product.productDescription }}
              Lorem ipsum dolor, sit amet consectetur adipisicing elit. Dolor eum quam dolore ratione aspernatur nobis. Assumenda dicta voluptatibus reiciendis repudiandae?
            &lt;/p&gt;
            &lt;VRating
              :model-value="product.rating"
              readonly
              density="compact"
              class="mb-2 d-block"
            /&gt;

            &lt;VList&gt;
              &lt;VListItem&gt;
                &lt;template #prepend&gt;
                  &lt;VIcon
                    icon="ri-circle-fill"
                    size="10"
                  /&gt;
                &lt;/template&gt;
                Lorem ipsum, dolor sit amet consectetur adipisicing elit. Culpa, deserunt!
              &lt;/VListItem&gt;
              &lt;VListItem&gt;
                &lt;template #prepend&gt;
                  &lt;VIcon
                    icon="ri-circle-fill"
                    size="10"
                  /&gt;
                &lt;/template&gt;
                Lorem ipsum, dolor sit amet consectetur adipisicing elit. Culpa, deserunt!
              &lt;/VListItem&gt;
              &lt;VListItem&gt;
                &lt;template #prepend&gt;
                  &lt;VIcon
                    icon="ri-circle-fill"
                    size="10"
                  /&gt;
                &lt;/template&gt;
                Lorem ipsum, dolor sit amet consectetur adipisicing elit. Culpa, deserunt!
              &lt;/VListItem&gt;
              &lt;VListItem&gt;
                &lt;template #prepend&gt;
                  &lt;VIcon
                    icon="ri-circle-fill"
                    size="10"
                  /&gt;
                &lt;/template&gt;
                Lorem ipsum, dolor sit amet consectetur adipisicing elit. Culpa, deserunt!
              &lt;/VListItem&gt;
            &lt;/VList&gt;

            &lt;VBtn
              prepend-icon="ri-shopping-cart-line"
              class="text-center"
              size="large"
              @click="quantity += 1"
            &gt;
              Add to Cart
            &lt;/VBtn&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/VCol&gt;
    &lt;/VRow&gt;
  &lt;/VCard&gt;
  &lt;div class="text-center"&gt;
    &lt;VBtn
      class="my-6 text-center"
      @click="() =&gt; router.push({ path: '/apps/ecommerce/products' })"
    &gt;
      Continue Shopping
    &lt;/VBtn&gt;
  &lt;/div&gt;
&lt;/template&gt;
</code></pre>
<p>On this page, we made an API request to our second API endpoint: <code>/api/ecommerce/products/:id</code>. This endpoint returns product details related to a given product ID. We will use this data on our page to display product details.</p>
<p>Let’s add routes for the e-commerce app. All the routes are located in the <strong>src/plugins/router/routes.ts</strong> file. In the file, add the e-commerce app’s routes.</p>
<pre><code class="lang-tsx">// file: src/plugins/router/routes.ts
{
  path: '/apps/ecommerce/products',
  component: () =&gt; import('@/pages/apps/ecommerce/products/index.vue'),
},
{
  name: 'apps-ecommerce-products-id',
  path: '/apps/ecommerce/products/:id',
  component: () =&gt; import('@/pages/apps/ecommerce/products/[id].vue'),
},
</code></pre>
<p>Now, let’s add an e-commerce app to our navigation menu. We'll list all our menu items and groups in <code>NavItems.vue</code> components. We'll use a <code>VerticalNavGroup</code> component for adding a nav group and a <code>VerticleNavLink</code> component for adding a nav item. For adding an e-commerce app in the navigation menu, add the code below in the <code>Apps &amp; Pages</code> section.</p>
<pre><code class="lang-tsx">//file: src/layouts/components/NavItems.vue

&lt;VerticalNavGroup
    :item="{
      title: 'e-commerce',
      icon: 'ri-shopping-cart-line',
    }"
  &gt;
    &lt;VerticalNavLink
      :item="{
        title: 'Shop',
        to: '/apps/ecommerce/products',
      }"
    /&gt;
    &lt;VerticalNavLink
      :item="{
        title: 'Product',
        to: { name: 'apps-ecommerce-products-id', params: { id: 1 } },
      }"
    /&gt;
&lt;/VerticalNavGroup&gt;
</code></pre>
<p>Congrats, you’ve built a Vue e-commerce app using Vue.js and MSW. You can visit the dev server to see the e-commerce app we just crafted.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, you built an e-commerce app using Vue.js and MSW to mock API calls. We created two main pages: the shop page to display products and the product details page to show product information.</p>
<p>The mock server setup helped us to create a realistic development environment without building an actual backend. At the end of this guide, you had a working e-commerce app prototype. This setup provides a strong foundation for further customization and development.</p>
<p>For the complete implementation of the e-commerce app built in this article, please refer to this GitHub repository: <a target="_blank" href="https://github.com/themeselection/e-commerce-app">https://github.com/themeselection/e-commerce-app</a>.</p>
<p>I hope you all find this article helpful. In case you want to develop a full-fledged e-commerce app, you can use the pre-built <a target="_blank" href="https://themeselection.com/item/category/vuejs-admin-templates/">Vuejs admin template</a> as it offers many components and features that can be helpful in creating a professional e-commerce app.</p>
<p>I have prepared this article with help of <a target="_blank" href="https://x.com/me_jd_solanki">Jayendrasinh Solanki</a>. He is an expert in VueJS with over 7 years of experience. BTW, he is followed by Vue creator Evan You! Isn't it great?</p>
<h3 id="heading-some-helpful-guides-for-e-commerce-product-development">Some helpful guides for e-commerce product development:</h3>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/develop-a-reusable-ecommerce-platform/">How to Develop a Reusable eCommerce Platform (freecodecamp.org)</a>.</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-an-ecommere-website-using-woocomerce/">How to Create an eCommerce Website Using WooCommerce (freecodecamp.org)</a>.</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
