<?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[ Design - 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[ Design - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Wed, 19 Aug 2026 13:21:00 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/design/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ A Deep Dive into Behavioral Patterns: The Visitor Design Pattern and its Clean Operations Across Complex Object Structures ]]>
                </title>
                <description>
                    <![CDATA[ There's a problem that shows up in almost every growing software system, and most developers don't even realize they're hitting it until the damage is already done. You have a set of objects: differen ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-visitor-design-pattern-and-its-clean-operations-across-complex-object-structures/</link>
                <guid isPermaLink="false">6a74b21fcf90c22a668963b6</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ design patterns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ design principles ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Dart ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mobile ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mobile Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software architecture ]]>
                    </category>
                
                    <category>
                        <![CDATA[ visitor design pattern ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwaseyi Fatunmole ]]>
                </dc:creator>
                <pubDate>Thu, 06 Aug 2026 16:11:11 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/ff25cbd5-72fc-4f17-8d37-ba8dc909de46.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>There's a problem that shows up in almost every growing software system, and most developers don't even realize they're hitting it until the damage is already done.</p>
<p>You have a set of objects: different types, shapes, and data. And at some point, someone asks you to perform an operation on all of them, like exporting them them to PDF, sending them a notification, generating a report, or calculating their fees.</p>
<p>Your first instinct might be to write a function that checks the type and branches accordingly, like an if-else block or switch statement. Something that says: if this is a NewUser, do this. If this is a JointAccountUser, do that. It works, you ship it, and everyone is happy.</p>
<p>Then another operation comes in. And another. Every single time, you go back to the same place and add another branch. The function grows. The class grows. The test surface grows. What started as a clean model is now a god object that knows how to do everything for everyone.</p>
<p>The Visitor Design Pattern exists to break this cycle completely.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-what-is-the-visitor-design-pattern">What is the Visitor Design Pattern?</a></p>
</li>
<li><p><a href="#heading-the-problem-the-visitor-pattern-solves">The Problem the Visitor Pattern Solves</a></p>
</li>
<li><p><a href="#heading-core-components">Core Components</a></p>
</li>
<li><p><a href="#heading-real-world-example-one-document-export">Real World Example One: Document Export</a></p>
</li>
<li><p><a href="#heading-real-world-example-two-notification-system">Real World Example Two: Notification System</a></p>
</li>
<li><p><a href="#heading-real-world-example-three-fee-calculation">Real World Example Three: Fee Calculation</a></p>
</li>
<li><p><a href="#heading-the-power-of-combining-all-three-operations">The Power of Combining All Three Operations</a></p>
</li>
<li><p><a href="#heading-when-to-use-the-visitor-pattern">When to Use the Visitor Pattern</a></p>
</li>
<li><p><a href="#heading-when-not-to-use-it">When Not to Use It</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-the-visitor-design-pattern">What is the Visitor Design Pattern?</h2>
<p>The Visitor pattern is a behavioral design pattern that lets you define a new operation on a family of objects without changing the objects themselves.</p>
<p>The key word there is behavioral. Behavioral patterns are about how objects communicate and distribute responsibility. Where creational patterns deal with how objects are created and structural patterns deal with how they are composed, behavioral patterns deal with how they interact and who is responsible for what.</p>
<p>The Visitor pattern specifically deals with the question of who should own an operation when that operation needs to work differently across multiple object types.</p>
<p>The classic answer is: put the operation on each object. Give each class a method that handles the operation for its own type. But this breaks down the moment you have multiple operations, because now every new operation means touching every class. You're spreading one concern across your entire object hierarchy.</p>
<p>The Visitor pattern flips this. Instead of spreading the operation across the objects, you collect it into one place called a Visitor. The objects simply accept the visitor and let it do its work. Adding a new operation means creating a new Visitor. The existing objects don't change at all.</p>
<p>This is the Open/Closed Principle working exactly as intended: open for extension, closed for modification.</p>
<h2 id="heading-the-problem-the-visitor-pattern-solves">The Problem the Visitor Pattern Solves</h2>
<p>Let me show you exactly what this looks like without the Visitor pattern.</p>
<p>Say you have a fintech platform with four types of users: existing customers, new customers, minor account holders, and joint account holders. Your product manager comes in and asks you to add document export. Every user type should be exportable to PDF, Excel, and CSV.</p>
<p>Without Visitor, the natural approach looks something like this:</p>
<pre><code class="language-dart">class ExistingUser {
  final int id;
  final String firstName;
  final String lastName;
  final DateTime lastPaymentDate;
  final num accountBalance;

  String exportToPdf() {
    return '$firstName\n$lastName\n$lastPaymentDate\n$accountBalance';
  }

  String exportToExcel() {
    return '$firstName,$lastName,$lastPaymentDate,$accountBalance';
  }

  String exportToCsv() {
    return '"$firstName","$lastName","$lastPaymentDate","$accountBalance"';
  }
}
</code></pre>
<p>And you repeat this for NewUser, MinorAccountUser, and JointAccountUser. Twelve methods spread across four classes just for document export.</p>
<p>Now the product manager comes back. They want notifications: email, SMS, and Push. Back you go to all four classes, adding three more methods each. Twelve more methods spread across the same four classes.</p>
<p>Then they want fee calculation. Then they want KYC status checks. Every new operation multiplies across every user type. The classes grow, the reasons to change multiply, and testing becomes painful.</p>
<p>This is the exact problem the Visitor pattern was built to solve.</p>
<h2 id="heading-core-components">Core Components</h2>
<p>The Visitor pattern has four core components. Understanding each one before looking at code makes the implementation much easier to follow.</p>
<h3 id="heading-the-visitor-interface">The Visitor Interface</h3>
<p>This is the contract that every visitor must implement. It declares one method per object type it needs to visit. A visitor that handles four user types declares four visit methods, one for each type.</p>
<h3 id="heading-the-concrete-visitors">The Concrete Visitors</h3>
<p>These are the real implementations of the Visitor interface. Each one represents a single operation and knows how to handle every object type. A PdfHandler is a concrete visitor. An ExcelHandler is a concrete visitor. A SmsNotificationHandler is a concrete visitor. Each one has one job and knows how to do that job for every user type.</p>
<h3 id="heading-the-consumer-interface-also-called-element-or-acceptor">The Consumer Interface (also called Element or Acceptor)</h3>
<p>This is the contract that every object in the hierarchy must implement. It declares a single accept method that takes a Visitor and calls the right visit method on it. This is the double dispatch mechanism that makes the pattern work.</p>
<h3 id="heading-the-concrete-consumers">The Concrete Consumers</h3>
<p>These are the real objects in the hierarchy: ExistingCustomers, NewCustomers, MinorCustomer, and JointCustomer. Each one implements accept by calling the specific visit method that corresponds to its own type.</p>
<p>Think of it this way. The Visitor interface is implemented by every operation you want to perform: PdfHandler, ExcelHandler, and CsvHandler. Each of these knows how to handle all four user types.</p>
<p>The Consumer interface is implemented by every object in the hierarchy: ExistingCustomers, NewCustomers, MinorCustomer, and JointCustomer. Each of these knows how to receive a visitor and route it to the correct method.</p>
<p>When you call <code>existingCustomer.accept(pdfHandler)</code>, ExistingCustomers calls <code>pdfHandler.visitExistingCustomer(this)</code> and passes itself as the argument. The right method fires automatically. There's no type checking, if-else, or switch. The object tells the visitor who it is, and the visitor knows exactly what to do with that information.</p>
<h2 id="heading-real-world-example-one-document-export">Real World Example One: Document Export</h2>
<p>This is a real scenario from a fintech platform. There are four user types with different data structures, all needing to export their information to three document formats: PDF, Excel, and CSV.</p>
<h3 id="heading-step-1-define-the-user-models">Step 1: Define the User Models</h3>
<pre><code class="language-dart">class ExistingUser {
  final int id;
  final String firstName;
  final String lastName;
  final DateTime lastPaymentDate;
  final num accountBalance;

  const ExistingUser({
    required this.id,
    required this.firstName,
    required this.lastName,
    required this.lastPaymentDate,
    required this.accountBalance,
  });
}

class NewUser {
  final String firstName;
  final String lastName;

  const NewUser({
    required this.firstName,
    required this.lastName,
  });
}

class MinorAccountUser {
  final int age;
  final int guardianId;
  final String firstName;
  final String lastName;
  final String guardianName;

  const MinorAccountUser({
    required this.age,
    required this.guardianId,
    required this.firstName,
    required this.lastName,
    required this.guardianName,
  });
}

class JointAccountUser {
  final int jointAccountId;
  final List&lt;String&gt; accountHoldersInfo;
  final num accountBalance;

  const JointAccountUser({
    required this.jointAccountId,
    required this.accountHoldersInfo,
    required this.accountBalance,
  });
}
</code></pre>
<p>We have four models. Each one owns its own data and nothing else. There's no export logic or notification logic. And no business operations of any kind. Just clean data structures.</p>
<p>This is exactly how it should be. The model's job is to hold data. The visitor's job is to operate on it.</p>
<h3 id="heading-step-2-define-the-visitor-and-consumer-interfaces">Step 2: Define the Visitor and Consumer Interfaces</h3>
<pre><code class="language-dart">abstract class UserVisitor&lt;T&gt; {
  T visitExistingCustomer(ExistingUser user);
  T visitNewCustomer(NewUser user);
  T visitMinorCustomer(MinorAccountUser user);
  T visitJointCustomer(JointAccountUser user);
}

abstract class UserConsumer {
  T accept&lt;T&gt;(UserVisitor&lt;T&gt; visitor);
}
</code></pre>
<p><code>UserVisitor&lt;T&gt;</code> is generic. The type parameter <code>T</code> represents what the visitor returns. A document export visitor returns a String. A fee calculation visitor might return a double. A validation visitor might return a bool. The same pattern works for any return type.</p>
<p><code>UserConsumer</code> declares the accept method. Every object in the hierarchy must implement this. The accept method is what makes the double dispatch work. The object receives the visitor and immediately calls the right visit method on it, passing itself as the argument.</p>
<h3 id="heading-step-3-implement-the-concrete-consumers">Step 3: Implement the Concrete Consumers</h3>
<pre><code class="language-dart">class ExistingCustomers implements UserConsumer {
  final ExistingUser user;
  ExistingCustomers({required this.user});

  @override
  T accept&lt;T&gt;(UserVisitor&lt;T&gt; visitor) {
    return visitor.visitExistingCustomer(user);
  }
}

class NewCustomers implements UserConsumer {
  final NewUser user;
  NewCustomers({required this.user});

  @override
  T accept&lt;T&gt;(UserVisitor&lt;T&gt; visitor) {
    return visitor.visitNewCustomer(user);
  }
}

class MinorCustomer implements UserConsumer {
  final MinorAccountUser user;
  MinorCustomer({required this.user});

  @override
  T accept&lt;T&gt;(UserVisitor&lt;T&gt; visitor) {
    return visitor.visitMinorCustomer(user);
  }
}

class JointCustomer implements UserConsumer {
  final JointAccountUser user;
  JointCustomer({required this.user});

  @override
  T accept&lt;T&gt;(UserVisitor&lt;T&gt; visitor) {
    return visitor.visitJointCustomer(user);
  }
}
</code></pre>
<p>Each consumer wraps one user model and implements accept by forwarding to the correct visit method. This is the entire job of a concrete consumer. It knows who it is, and it tells the visitor by calling the right method.</p>
<p>Notice that none of these classes know anything about PDF, Excel, CSV, email, SMS, or any operation. They're completely decoupled from every operation that will ever be performed on them.</p>
<h3 id="heading-step-4-implement-the-concrete-visitors">Step 4: Implement the Concrete Visitors</h3>
<pre><code class="language-dart">class PdfHandler implements UserVisitor&lt;String&gt; {
  @override
  String visitExistingCustomer(ExistingUser user) {
    return '${user.firstName} ${user.lastName}'
        '\nBalance: ${user.accountBalance}'
        '\nLast Payment: ${user.lastPaymentDate}';
  }

  @override
  String visitNewCustomer(NewUser user) {
    return '${user.firstName} ${user.lastName}';
  }

  @override
  String visitMinorCustomer(MinorAccountUser user) {
    return '${user.firstName} ${user.lastName}'
        '\nAge: ${user.age}'
        '\nGuardian: ${user.guardianName} (ID: ${user.guardianId})';
  }

  @override
  String visitJointCustomer(JointAccountUser user) {
    final holders = user.accountHoldersInfo.join(', ');
    return 'Joint Account ID: ${user.jointAccountId}'
        '\nHolders: $holders'
        '\nBalance: ${user.accountBalance}';
  }
}

class ExcelHandler implements UserVisitor&lt;String&gt; {
  @override
  String visitExistingCustomer(ExistingUser user) {
    return '${user.firstName}\t${user.lastName}'
        '\t${user.accountBalance}\t${user.lastPaymentDate}';
  }

  @override
  String visitNewCustomer(NewUser user) {
    return '${user.firstName}\t${user.lastName}';
  }

  @override
  String visitMinorCustomer(MinorAccountUser user) {
    return '${user.firstName}\t${user.lastName}'
        '\t${user.age}\t${user.guardianName}\t${user.guardianId}';
  }

  @override
  String visitJointCustomer(JointAccountUser user) {
    final holders = user.accountHoldersInfo.join('\t');
    return '${user.jointAccountId}\t$holders\t${user.accountBalance}';
  }
}

class CsvHandler implements UserVisitor&lt;String&gt; {
  @override
  String visitExistingCustomer(ExistingUser user) {
    return '"${user.firstName}","${user.lastName}"'
        ',"${user.accountBalance}","${user.lastPaymentDate}"';
  }

  @override
  String visitNewCustomer(NewUser user) {
    return '"${user.firstName}","${user.lastName}"';
  }

  @override
  String visitMinorCustomer(MinorAccountUser user) {
    return '"${user.firstName}","${user.lastName}"'
        ',"${user.age}","${user.guardianName}","${user.guardianId}"';
  }

  @override
  String visitJointCustomer(JointAccountUser user) {
    final holders = user.accountHoldersInfo.map((h) =&gt; '"$h"').join(',');
    return '"${user.jointAccountId}",$holders,"${user.accountBalance}"';
  }
}
</code></pre>
<p>Each handler implements the visitor interface and knows exactly how to format each user type for its specific document format. PdfHandler uses newlines and labels. ExcelHandler uses tabs. CsvHandler wraps values in quotes and separates with commas.</p>
<p>The formatting logic for each document type lives in exactly one class. If the PDF format changes, you touch only PdfHandler. If the CSV format changes, you touch only CsvHandler. The user models never change.</p>
<h3 id="heading-step-5-use-it">Step 5: Use It</h3>
<pre><code class="language-dart">void existingUserLogic() {
  final customer = ExistingCustomers(
    user: ExistingUser(
      id: 10,
      firstName: 'Oluwaseyi',
      lastName: 'Fatunmole',
      lastPaymentDate: DateTime.now(),
      accountBalance: 7373773.39,
    ),
  );

  final pdf = customer.accept(PdfHandler());
  final excel = customer.accept(ExcelHandler());
  final csv = customer.accept(CsvHandler());

  print('PDF:\n$pdf\n');
  print('Excel:\n$excel\n');
  print('CSV:\n$csv\n');
}

void newUserLogic() {
  final customer = NewCustomers(
    user: NewUser(
      firstName: 'Oluwaseyi',
      lastName: 'Fatunmole',
    ),
  );

  customer.accept(PdfHandler());
  customer.accept(ExcelHandler());
  customer.accept(CsvHandler());
}

void minorUserLogic() {
  final customer = MinorCustomer(
    user: MinorAccountUser(
      age: 15,
      guardianId: 82882,
      firstName: 'Oluwaseyi',
      lastName: 'Fatunmole',
      guardianName: 'Inioluwa',
    ),
  );

  customer.accept(PdfHandler());
  customer.accept(ExcelHandler());
  customer.accept(CsvHandler());
}

void jointUserLogic() {
  final customer = JointCustomer(
    user: JointAccountUser(
      jointAccountId: 92,
      accountHoldersInfo: [
        'Oluwaseyi',
        'Aderonke',
        'Inioluwa',
        'Tiwaloluwa',
      ],
      accountBalance: 9200020202.22,
    ),
  );

  customer.accept(PdfHandler());
  customer.accept(ExcelHandler());
  customer.accept(CsvHandler());
}
</code></pre>
<p>The same customer object accepts any visitor with the same call. The type dispatch happens automatically through the accept method. There's no type checking anywhere in the calling code, and no if-else or switch. Just <code>customer.accept(handler)</code> and the right method fires.</p>
<p>Now think about what happens when you need to add an XML export. You create one new class, XmlHandler, implement the four visit methods, and that's it. You don't touch ExistingUser, NewUser, MinorAccountUser, JointAccountUser, or any of the existing handlers. The system is genuinely open for extension and closed for modification.</p>
<h2 id="heading-real-world-example-two-notification-system">Real World Example Two: Notification System</h2>
<p>Here we have the same four user types and the same pattern. But it's a different operation entirely.</p>
<p>Your platform needs to notify users about account events. But not every user type should be notified the same way.</p>
<p>Existing users get email and push notifications. New users only get email because they haven't fully set up their profile yet. Minor account users get SMS to their guardian's number. Joint account users get notified on all channels because multiple people share the account.</p>
<p>Without the Visitor pattern, this logic would spread across all four user models or collapse into one enormous function full of type checks. With Visitor, it lives in three focused classes.</p>
<h3 id="heading-the-notification-visitor-interface">The Notification Visitor Interface</h3>
<pre><code class="language-dart">abstract class NotificationVisitor {
  void visitExistingCustomer(ExistingUser user);
  void visitNewCustomer(NewUser user);
  void visitMinorCustomer(MinorAccountUser user);
  void visitJointCustomer(JointAccountUser user);
}
</code></pre>
<p>This visitor returns void because notifications are side effects. They send messages, they don't return values.</p>
<h3 id="heading-the-concrete-notification-visitors">The Concrete Notification Visitors</h3>
<pre><code class="language-dart">class EmailNotificationHandler implements NotificationVisitor {
  @override
  void visitExistingCustomer(ExistingUser user) {
    print('Sending email to existing customer: ${user.firstName}');
    // email service call with full account details
  }

  @override
  void visitNewCustomer(NewUser user) {
    print('Sending welcome email to new customer: ${user.firstName}');
    // welcome email with onboarding steps
  }

  @override
  void visitMinorCustomer(MinorAccountUser user) {
    print('Sending email to guardian: ${user.guardianName}');
    // email goes to guardian, not the minor
  }

  @override
  void visitJointCustomer(JointAccountUser user) {
    for (final holder in user.accountHoldersInfo) {
      print('Sending email to joint holder: $holder');
      // all account holders get notified
    }
  }
}

class SmsNotificationHandler implements NotificationVisitor {
  @override
  void visitExistingCustomer(ExistingUser user) {
    print('Sending SMS to existing customer: ${user.firstName}');
  }

  @override
  void visitNewCustomer(NewUser user) {
    // new users are not SMS-verified yet, skip
    print('New customer ${user.firstName} not SMS-eligible yet');
  }

  @override
  void visitMinorCustomer(MinorAccountUser user) {
    print('Sending SMS to guardian ${user.guardianName} for minor ${user.firstName}');
    // SMS goes to guardian's registered number
  }

  @override
  void visitJointCustomer(JointAccountUser user) {
    for (final holder in user.accountHoldersInfo) {
      print('Sending SMS to joint holder: $holder');
    }
  }
}

class PushNotificationHandler implements NotificationVisitor {
  @override
  void visitExistingCustomer(ExistingUser user) {
    print('Push notification to existing customer: ${user.firstName}');
  }

  @override
  void visitNewCustomer(NewUser user) {
    print('Push notification to new customer: ${user.firstName}');
  }

  @override
  void visitMinorCustomer(MinorAccountUser user) {
    // minors do not have the app installed yet, guardian gets push
    print('Push notification to guardian: ${user.guardianName}');
  }

  @override
  void visitJointCustomer(JointAccountUser user) {
    for (final holder in user.accountHoldersInfo) {
      print('Push notification to joint holder: $holder');
    }
  }
}
</code></pre>
<p>Each handler knows the specific rules for each user type. <code>SmsNotificationHandler</code> knows that new users aren't SMS-verified yet. <code>PushNotificationHandler</code> knows that minor account notifications go to the guardian. <code>EmailNotificationHandler</code> knows that joint account holders all need to be notified individually.</p>
<p>This business logic lives in exactly one place per notification channel. When the rules change (and they always change), you update one class.</p>
<h3 id="heading-using-the-notification-visitors">Using the Notification Visitors</h3>
<pre><code class="language-dart">void notifyExistingUser() {
  final customer = ExistingCustomers(
    user: ExistingUser(
      id: 10,
      firstName: 'Oluwaseyi',
      lastName: 'Fatunmole',
      lastPaymentDate: DateTime.now(),
      accountBalance: 7373773.39,
    ),
  );

  customer.accept(EmailNotificationHandler());
  customer.accept(SmsNotificationHandler());
  customer.accept(PushNotificationHandler());
}

void notifyMinorUser() {
  final customer = MinorCustomer(
    user: MinorAccountUser(
      age: 15,
      guardianId: 82882,
      firstName: 'Oluwaseyi',
      lastName: 'Fatunmole',
      guardianName: 'Inioluwa',
    ),
  );

  // all three channels fire, each with minor-specific rules
  customer.accept(EmailNotificationHandler());
  customer.accept(SmsNotificationHandler());
  customer.accept(PushNotificationHandler());
}

void notifyJointUser() {
  final customer = JointCustomer(
    user: JointAccountUser(
      jointAccountId: 92,
      accountHoldersInfo: [
        'Oluwaseyi',
        'Aderonke',
        'Inioluwa',
        'Tiwaloluwa',
      ],
      accountBalance: 9200020202.22,
    ),
  );

  customer.accept(EmailNotificationHandler());
  customer.accept(SmsNotificationHandler());
  customer.accept(PushNotificationHandler());
}
</code></pre>
<p>The calling code is identical regardless of the user type or the notification channel. The dispatch is automatic. The rules live inside the visitors.</p>
<p>When WhatsApp notifications become a requirement (and they will), you create one <code>WhatsAppNotificationHandler</code> class with four visit methods. Nothing else changes.</p>
<h2 id="heading-real-world-example-three-fee-calculation">Real World Example Three: Fee Calculation</h2>
<p>Again, we have the same four user types and the same pattern. And once again, we have a completely different operation.</p>
<p>Your platform needs to calculate monthly maintenance fees. But each user type has different rules.</p>
<p>Existing customers pay a flat monthly fee based on their account balance. New customers are fee-exempt for their first three months. Minor account holders pay a reduced fee because their accounts have restricted features. Joint account holders have their fee split equally across all account holders.</p>
<p>Without Visitor, this logic ends up as a giant method somewhere with four branches, or worse, it leaks into the user models themselves. With Visitor, it lives in one focused class.</p>
<h3 id="heading-the-fee-visitor-interface">The Fee Visitor Interface</h3>
<pre><code class="language-dart">abstract class FeeVisitor {
  double visitExistingCustomer(ExistingUser user);
  double visitNewCustomer(NewUser user);
  double visitMinorCustomer(MinorAccountUser user);
  double visitJointCustomer(JointAccountUser user);
}
</code></pre>
<p>This visitor returns a double because fee calculation produces a numeric value.</p>
<h3 id="heading-the-concrete-fee-visitor">The Concrete Fee Visitor</h3>
<pre><code class="language-dart">class MonthlyFeeCalculator implements FeeVisitor {
  @override
  double visitExistingCustomer(ExistingUser user) {
    // 0.5% of account balance, minimum 500, maximum 5000
    final fee = user.accountBalance * 0.005;
    return fee.clamp(500, 5000).toDouble();
  }

  @override
  double visitNewCustomer(NewUser user) {
    // new customers are fee-exempt for the first 3 months
    return 0.0;
  }

  @override
  double visitMinorCustomer(MinorAccountUser user) {
    // flat reduced fee for minor accounts
    return 150.0;
  }

  @override
  double visitJointCustomer(JointAccountUser user) {
    // standard fee split equally across all holders
    const standardFee = 2000.0;
    return standardFee / user.accountHoldersInfo.length;
  }
}
</code></pre>
<p>Every fee rule for every user type lives in this one class. When the fee structure changes for existing customers, you touch one method in one class. When minor account fees are updated, same thing. None of the user models change, and no other visitor changes.</p>
<h3 id="heading-using-the-fee-visitor">Using the Fee Visitor</h3>
<pre><code class="language-dart">void calculateFees() {
  final existingCustomer = ExistingCustomers(
    user: ExistingUser(
      id: 10,
      firstName: 'Oluwaseyi',
      lastName: 'Fatunmole',
      lastPaymentDate: DateTime.now(),
      accountBalance: 7373773.39,
    ),
  );

  final newCustomer = NewCustomers(
    user: NewUser(
      firstName: 'Aderonke',
      lastName: 'Fatunmole',
    ),
  );

  final minorCustomer = MinorCustomer(
    user: MinorAccountUser(
      age: 15,
      guardianId: 82882,
      firstName: 'Inioluwa',
      lastName: 'Fatunmole',
      guardianName: 'Oluwaseyi',
    ),
  );

  final jointCustomer = JointCustomer(
    user: JointAccountUser(
      jointAccountId: 92,
      accountHoldersInfo: [
        'Oluwaseyi',
        'Aderonke',
        'Inioluwa',
        'Tiwaloluwa',
      ],
      accountBalance: 9200020202.22,
    ),
  );

  final calculator = MonthlyFeeCalculator();

  final existingFee = existingCustomer.accept(calculator);
  final newFee = newCustomer.accept(calculator);
  final minorFee = minorCustomer.accept(calculator);
  final jointFee = jointCustomer.accept(calculator);

  print('Existing customer fee: NGN $existingFee');
  print('New customer fee: NGN $newFee');
  print('Minor account fee: NGN $minorFee');
  print('Joint account fee per holder: NGN $jointFee');
}
</code></pre>
<p>The output:</p>
<pre><code class="language-plaintext">Existing customer fee: NGN 5000.0
New customer fee: NGN 0.0
Minor account fee: NGN 150.0
Joint account fee per holder: NGN 500.0
</code></pre>
<p>When a <code>PremiumFeeCalculator</code> is needed for a new tier of customers, you create one new class that implements <code>FeeVisitor</code>. The user models stay exactly as they are. The <code>MonthlyFeeCalculator</code> stays exactly as it is. The accept methods on all four consumers stay exactly as they are.</p>
<h2 id="heading-the-power-of-combining-all-three-operations">The Power of Combining All Three Operations</h2>
<p>Here's what makes the Visitor pattern truly shine in a system like this. You have the same four user types, and you can run any combination of visitors on any of them in the same call chain.</p>
<pre><code class="language-dart">void processUser(UserConsumer customer) {
  final pdf = customer.accept(PdfHandler());
  final csv = customer.accept(CsvHandler());

  customer.accept(EmailNotificationHandler());
  customer.accept(PushNotificationHandler());

  final fee = customer.accept(MonthlyFeeCalculator());

  print('Fee: NGN $fee');
  print('Documents generated and notifications sent');
}
</code></pre>
<p>One function, any user type, any combination of operations. The consumer doesn't care which visitors it receives. The visitors don't care which consumers call them. They speak to each other through the interface, and the interface guarantees everything works correctly.</p>
<p>We have three completely different operations (document export, notifications, and fee calculation) all applied to the same object with the same call pattern. None of these operations know about each other. None of them touch the user models. Each one lives in its own focused class with its own single reason to change.</p>
<h2 id="heading-when-to-use-the-visitor-pattern">When to Use the Visitor Pattern</h2>
<p>Use Visitor when you have a stable set of object types and a growing set of operations on them.</p>
<p>The pattern shines when the object hierarchy is unlikely to change frequently. It's optimized for adding new operations, not new types. Adding a new user type means updating every existing visitor. If your object types change constantly, Visitor creates more work than it saves.</p>
<p>It's also very effective when you need to perform multiple unrelated operations on a family of objects without polluting their classes with that logic. Document export, notification handling, fee calculation, and KYC validation are all unrelated operations. Each belongs in its own visitor, not scattered across the user models.</p>
<p>Visitor also works well when you want clean separation between data and behavior. The models hold data and the visitors define behavior. This makes both easier to understand, easier to test, and easier to maintain independently.</p>
<h2 id="heading-when-not-to-use-it">When Not to Use It</h2>
<p>Avoid Visitor when the object hierarchy changes frequently. Every time you add a new type, you must update every existing visitor. In a system where new user types appear regularly, this becomes painful quickly.</p>
<p>It's also not helpful when you only have one or two operations. For simple cases, the overhead of creating visitor interfaces, consumer interfaces, and multiple classes is not worth the benefit.</p>
<p>And avoid it when the operations are tightly coupled to the object's internal state in ways that make sense to keep together. Some behavior naturally belongs on the object itself.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The Visitor Design Pattern solves a problem that most developers only recognize after they've already made a mess of it. You have a family of objects with different types and different data. Operations come in one after another. Without a deliberate structure, those operations spread everywhere: into the models, utility classes, and massive switch statements that nobody wants to touch.</p>
<p>Visitor collects each operation into one focused class. The models stay clean and the operations stay isolated. Adding a new operation means creating one new class. The existing code doesn't change.</p>
<p>In the fintech examples above, we have three entirely different concerns: document export, notifications, and fee calculation. All are handled by handled by focused classes, none of which know anything about each other. The user models don't know about PDF or email or fees. The PdfHandler doesn't know about SMS. The MonthlyFeeCalculator doesn't know about push notifications. Each class has exactly one reason to exist and exactly one reason to change.</p>
<p>That s what a well-applied Visitor pattern looks like in practice. Clean, focused, and genuinely extensible.</p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Implement Privacy by Design in Modern APIs – A Developer's Practical Guide ]]>
                </title>
                <description>
                    <![CDATA[ As software developers, we're usually taught to prioritize features like speed, performance, and uptime. When we build APIs, our core concern is making sure data gets from Point A to Point B smoothly. ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-implement-privacy-by-design-in-modern-apis/</link>
                <guid isPermaLink="false">6a71e6ca56867ecf2f5d78c1</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ APIs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ privacy ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer Tools ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ samiatakande ]]>
                </dc:creator>
                <pubDate>Tue, 04 Aug 2026 13:19:06 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/2c0c5da0-cf2d-4414-9486-40be7a04f727.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As software developers, we're usually taught to prioritize features like speed, performance, and uptime. When we build APIs, our core concern is making sure data gets from Point A to Point B smoothly.</p>
<p>But data privacy regulations are tightening globally, and users are growing increasingly conscious of their digital footprints. Treating privacy as a "legal afterthought" or something to fix later in production is no longer sustainable.</p>
<p>This is where <strong>Privacy by Design</strong> comes in.</p>
<p>Coined as a framework to integrate privacy proactively into the engineering lifecycle, Privacy by Design means your system architecture should naturally protect user data by default.</p>
<p>In this comprehensive guide, we'll walk through how to structurally build data privacy into your backend APIs using modern engineering patterns, code concepts, and intentional database designs.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a href="#heading-the-principles-of-privacy-by-design-for-developers">The Principles of Privacy by Design for Developers</a></p>
</li>
<li><p><a href="#heading-project-directory-structure">Project Directory Structure</a></p>
</li>
<li><p><a href="#heading-implement-strict-data-minimization-at-the-endpoint-layer">Implement Strict Data Minimization at the Endpoint Layer</a></p>
</li>
<li><p><a href="#heading-decouple-pii-with-the-pseudonymization-token-pattern">Decouple PII with the Pseudonymization Token Pattern</a></p>
</li>
<li><p><a href="#heading-beyond-rbac-implementing-policy-based-access-control-pbac">Beyond RBAC: Implementing Policy-Based Access Control (PBAC)</a></p>
</li>
<li><p><a href="#heading-automate-data-retention-with-database-ttls-and-hooks">Automate Data Retention with Database TTLs and Hooks</a></p>
</li>
<li><p><a href="#heading-trust-is-the-ultimate-developer-metric">Trust is the Ultimate Developer Metric</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before diving into this tutorial, you should have the following:</p>
<ul>
<li><p>A foundational understanding of Node.js and JavaScript (ES6+).</p>
</li>
<li><p>Familiarity with building basic RESTful APIs using Express.</p>
</li>
<li><p>Essential knowledge of database interactions (SQL or NoSQL concepts).</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a5100d76df448adcc03e031/a423a8ed-9d57-4ab4-8617-d2ceb2fbfa31.png" alt="a423a8ed-9d57-4ab4-8617-d2ceb2fbfa31" style="display:block;margin:0 auto" width="542" height="610" loading="lazy"></li>
</ul>
<p><em>Figure 1: The four pillars of Privacy by Design for backend APIs.</em></p>
<blockquote>
<p><strong>Diagram Breakdown:</strong></p>
<ul>
<li><p><strong>Center:</strong> Core security shield representing privacy-first system design.</p>
</li>
<li><p><strong>Top-Left (Data Minimization):</strong> Payload filtering at the endpoint layer.</p>
</li>
<li><p><strong>Top-Right (Pseudonymization):</strong> Decoupling PII via tokenization.</p>
</li>
<li><p><strong>Bottom-Left (PBAC):</strong> Purpose-driven, context-aware authorization rules.</p>
</li>
<li><p><strong>Bottom-Right (Retention &amp; TTL):</strong> Automated data expiration via database hooks.</p>
</li>
</ul>
</blockquote>
<h2 id="heading-the-principles-of-privacy-by-design-for-developers">The Principles of Privacy by Design for Developers</h2>
<p>Before writing code, we need to shift our mindset. Privacy by Design isn't about writing a better "Privacy Policy" page on a website. It means translating structural abstractions into practical engineering boundaries.</p>
<p>For an API engineer, this boils down to four distinct execution pillars:</p>
<ul>
<li><p><strong>Proactive, not reactive:</strong> Preventing privacy data leaks before they happen rather than managing breaches after the fact.</p>
</li>
<li><p><strong>Privacy as the default:</strong> The user doesn't have to opt-in to remain private. The ecosystem protects them out of the box.</p>
</li>
<li><p><strong>End-to-end security:</strong> Data remains secure, structured, and minimized from ingestion to permanent deletion.</p>
</li>
<li><p><strong>Visibility and transparency:</strong> Keeping clean logs of what data is handled, where it lives, and why it is being used.</p>
</li>
</ul>
<p>Let's look at how we can implement these four foundations directly inside our codebases.</p>
<h2 id="heading-project-directory-structure">Project Directory Structure</h2>
<p>To give you a technical perspective of how these privacy patterns fit together cleanly inside a modular production application, we'll be referencing code across the following project layout:</p>
<pre><code class="language-text">api-privacy-design/
├── config/
│   └── database.js
├── middleware/
│   ├── auth.js
│   └── privacyPolicy.js
├── models/
│   ├── auditLog.js
│   └── user.js
├── services/
│   └── piiVault.js
├── validators/
│   └── userValidator.js
├── app.js
├── package.json
└── README.md
</code></pre>
<h2 id="heading-implement-strict-data-minimization-at-the-endpoint-layer">Implement Strict Data Minimization at the Endpoint Layer</h2>
<p>The fundamental rule of data privacy is simple: <strong>If you don’t have it, you can't lose it.</strong></p>
<h3 id="heading-the-payload-over-inclusion-anti-pattern">The Payload Over-Inclusion Anti-Pattern</h3>
<p>Many APIs accept massive, generic JSON payloads from frontend clients and save everything straight to the database. Developers often do this for convenience, using spread operators like <code>...req.body</code> to quickly insert records without explicitly mapping variables.</p>
<pre><code class="language-javascript">// A poorly designed registration endpoint that grabs everything indiscriminately
app.post('/api/register', async (req, res) =&gt; {
  const userData = req.body; // Accepts full profile, tracking tokens, internal metadata, etc.
  const user = await Database.save('users', userData);
  res.status(201).json(user);
});
</code></pre>
<p>If an attacker manipulates the client-side request to pass an administrative flag like <code>{"isAdmin": true, "internalDeviceID": "123"}</code> within the payload, a naïve endpoint will process it.</p>
<h3 id="heading-architectural-view-schema-validation">Architectural View: Schema Validation</h3>
<p>Data minimization means configuring endpoints to accept and store only what is strictly necessary for immediate business operations. To enforce this, explicit schema validation must occur right at the API gateway or controller boundary. This process ensures that only predefined, safe fields enter your internal system, and everything else is structurally ignored.</p>
<h3 id="heading-the-code-solution-schema-hardening">The Code Solution: Schema Hardening</h3>
<p>By implementing strict verification models (using validation libraries like Joi, Zod, or Yup), any unmapped field injected by a client is dropped or triggers a validation block.</p>
<p>Under our <code>validators/userValidator.js</code> configuration file, we can define our schema parameters.</p>
<p>If your validation provider is Joi-compatible, you can leverage native options like <code>{ stripUnknown: true }</code> to automatically clean incoming objects. If you choose to use an alternate validation framework like Zod, you can achieve an identical outcome by chaining the <code>.strict()</code> modifier to block requests that contain unmapped fields entirely.</p>
<p>Here's how we use Joi to drop non-explicit fields instantly at our router boundary:</p>
<pre><code class="language-javascript">const Joi = require('joi');

// Explicitly define the bare minimum schema required for validation
const registrationSchema = Joi.object({
  email: Joi.string().email().required(),
  password: Joi.string().min(8).required()
  // Any extra tracking metadata or unauthorized attributes injected here are dropped automatically
});

app.post('/api/register', async (req, res) =&gt; {
  try {
    // stripUnknown: true drops any properties not explicitly defined in the schema
    const validatedData = await registrationSchema.validateAsync(req.body, { stripUnknown: true });
    
    const user = await Database.save('users', validatedData);
    
    // Privacy Safeguard: Never return raw internal properties back to the client response
    res.status(201).json({ id: user.id, email: user.email }); 
  } catch (err) {
    res.status(400).json({ error: err.details[0].message });
  }
});
</code></pre>
<h2 id="heading-decouple-pii-with-the-pseudonymization-token-pattern">Decouple PII with the Pseudonymization Token Pattern</h2>
<p>When handling Personally Identifiable Information (PII) like real names, phone numbers, or physical home addresses, storing them in plain text inside your primary application tables is a massive security liability.</p>
<h3 id="heading-why-simple-encryption-isnt-enough">Why Simple Encryption Isn't Enough</h3>
<p>While encrypting columns at rest (using AES-256) is standard practice, application systems still face risks. If developers run analytical reporting, dump operational data into debugging environments, or accidentally output database rows to application logs (for example, <code>console.log(userObject)</code>), raw sensitive data can quickly spill across unauthorized environments.</p>
<h3 id="heading-the-tokenization-architecture">The Tokenization Architecture</h3>
<p>Instead of keeping PII alongside business tables, use a <strong>Pseudonymization Token Pattern</strong>. This separates identity from transactional records. This isn't just encryption anymore; it's an architectural separation of duties.</p>
<h3 id="heading-implementing-a-pseudonymized-data-flow">Implementing a Pseudonymized Data Flow</h3>
<p>Let's trace how the processing layer functions. In our isolated <code>services/piiVault.js</code> module, we manage the interaction between our primary app controller and our secure token storage vault. When a record initialisation occurs, we isolate the raw PII elements, exchange them for an opaque reference token, and use that reference token as our relational key.</p>
<pre><code class="language-javascript">// services/piiVault.js
// Conceptual abstraction of a decoupled user account initialization
async function createUserProfile(incomingPayload) {
  const { email, phoneNumber, ...transactionalData } = incomingPayload;

  // 1. Dispatch the raw PII elements directly to an isolated, encrypted Vault Service
  const vaultResponse = await PiiVaultService.tokenize({
    email: email,
    phone: phoneNumber
  });

  // 2. The Vault returns a uniquely structured reference UUID token (non-reversible string)
  const piiToken = vaultResponse.token; // e.g., "pii_token_83912x"

  // 3. Save the primary application record using ONLY the token link
  const operationalRecord = {
    ...transactionalData,
    piiRefToken: piiToken,
    accountStatus: 'active',
    createdAt: new Date()
  };

  await Database.save('primary_users_table', operationalRecord);
  return { success: true, reference: piiToken };
}
</code></pre>
<p>If internal developers run analytical operations or debug logs on the primary backend database, they'll only ever see non-identifiable reference strings rather than actual user credentials.</p>
<h2 id="heading-beyond-rbac-implementing-policy-based-access-control-pbac">Beyond RBAC: Implementing Policy-Based Access Control (PBAC)</h2>
<p>Traditional Role-Based Access Control (RBAC) (checking patterns like <code>if (user.role === 'admin')</code>) is no longer granular enough for complex software architectures. Privacy engineering demands that access control systems evaluate not just <em>who</em> is trying to view a resource, but the <em>purpose</em> of the access request.</p>
<h3 id="heading-the-core-vectors-of-pbac">The Core Vectors of PBAC</h3>
<p>By transitioning to Policy-Based Access Control (PBAC), your authorization system dynamically maps rules along three parameters:</p>
<ul>
<li><p><strong>The Actor/User:</strong> Who is making the API call and what are their active permissions?</p>
</li>
<li><p><strong>The Resource:</strong> What specific classification of data is being requested?</p>
</li>
<li><p><strong>The Purpose:</strong> Why does the business logic need to process this data, and did the data owner explicitly give consent for it?</p>
</li>
</ul>
<h3 id="heading-building-contextual-privacy-governance-middleware">Building Contextual Privacy Governance Middleware</h3>
<p>Let's see how this works in practice. To set the context for our route execution, we'll build a dedicated authorization middleware file under <code>middleware/privacyPolicy.js</code>. This middleware intercepts the incoming request vector, checks the destination resource owner's privacy choices, and matches it against the application's processing target context.</p>
<pre><code class="language-javascript">// middleware/privacyPolicy.js
// Middleware pattern verifying purpose-bound consent parameters
const verifyDataAccessPolicy = (requiredPurpose) =&gt; {
  return (req, res, next) =&gt; {
    const actor = req.user; // Instantiated from a previous authentication layer
    const resourceOwner = req.resourceOwner; // The target data record context
    
    // Extract the explicit consent array configured by the user
    const userConsentPolicies = resourceOwner.consents || []; // e.g., ['essential_auth', 'marketing_emails']

    // Check if the code execution purpose matches what the user explicitly consented to
    const hasExplicitConsent = userConsentPolicies.includes(requiredPurpose);
    
    // Elevate override permissions ONLY to specialized audit actors if explicitly tracked
    if (!hasExplicitConsent &amp;&amp; actor.role !== 'System_Auditor') {
      return res.status(403).json({ 
        error: "Access Denied: The operation requested exceeds your current purpose-bound user consent profiles." 
      });
    }
    
    // Access authorized; proceed down the middleware track
    next();
  };
};

// Application Execution Target Route within app.js
app.get('/api/analytics/user-behavior/:userId', 
  fetchResourceOwnerMiddleware, 
  verifyDataAccessPolicy('analytics_tracking'), // Will throw a 403 if user opted out of tracking
  (req, res) =&gt; {
    res.json({ status: "Success", data: "Contextual processing executed." });
  }
);
</code></pre>
<h2 id="heading-automate-data-retention-with-database-ttls-and-hooks">Automate Data Retention with Database TTLs and Hooks</h2>
<p>Data privacy frameworks emphasize that user data shouldn't sit inside database storage indefinitely. If a temporary log has fulfilled its purpose, or an account lifecycle ends, that data needs to disappear entirely.</p>
<h3 id="heading-the-automated-retention-lifecycle">The Automated Retention Lifecycle</h3>
<p>Relying on teams to run manual script updates or cron cleanup commands is prone to failure. Privacy-by-design systems build data expiration rules directly into their data models.</p>
<h3 id="heading-document-stores-native-ttl-indexes">Document Stores: Native TTL Indexes</h3>
<p>If you're managing unstructured payload layers or tracking sessions in NoSQL document collections (like MongoDB), you can leverage Time-To-Live (TTL) index configurations to wipe records automatically down to the second.</p>
<p>We write this logic directly into our schemas inside <code>models/auditLog.js</code>:</p>
<pre><code class="language-javascript">// models/auditLog.js
const mongoose = require('mongoose');

const auditLogSchema = new mongoose.Schema({
  userId: mongoose.Schema.Types.ObjectId,
  apiAction: String,
  ipAddress: String,
  createdAt: { 
    type: Date, 
    default: Date.now, 
    expires: '90d' // MongoDB background threads automatically drop this document after 90 days
  }
});

const AuditLog = mongoose.model('AuditLog', auditLogSchema);
</code></pre>
<h3 id="heading-relational-databases-safe-masking-with-orm-hooks">Relational Databases: Safe Masking with ORM Hooks</h3>
<p>In relational database systems (such as PostgreSQL or MySQL using Sequelize/Prisma), cascading relationships make immediate hard deletions tricky.</p>
<p>To avoid breaking database foreign keys while still respecting user privacy, we implement a two-step pattern: an instantaneous lifecycle hook handles data anonymisation and masking, while a native database scheduled script handles data cleansing asynchronously.</p>
<p>We can implement this hook inside our relational schema files under <code>models/user.js</code>:</p>
<pre><code class="language-javascript">// models/user.js
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('sqlite::memory:');

const OperationalUser = sequelize.define('OperationalUser', {
  username: DataTypes.STRING,
  email: DataTypes.STRING,
  fullName: DataTypes.STRING,
  isDeleted: { type: DataTypes.BOOLEAN, defaultValue: false }
});

// Anonymize records on the fly before a soft-deletion hook runs
OperationalUser.addHook('beforeUpdate', async (user, options) =&gt; {
  if (user.isDeleted &amp;&amp; user.changed('isDeleted')) {
    // Mask and overwrite confidential fields to protect privacy while keeping non-PII metrics intact
    user.email = `anonymized_user_${Date.now()}@privacy-protected.org`;
    user.fullName = "Anonymized Profile Data";
    user.username = `archived_node_${Math.floor(Math.random() * 100000)}`;
  }
});
</code></pre>
<h2 id="heading-trust-is-the-ultimate-developer-metric">Trust is the Ultimate Developer Metric</h2>
<p>Building high-throughput applications quickly is a fantastic skill, but engineering architectures that stand the test of time requires building for trust.</p>
<p>When you embed consent boundaries, strict payload validation schema controls, decoupled identifier vaults, and automated database retention routines into your backend services from day one, you aren't just checking boxes off a security compliance form. You're building reliable, loosely coupled code systems that mitigate data breach risks and treat user privacy as a first-class citizen in application design.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Marketing Landing Page Using shadcn/ui ]]>
                </title>
                <description>
                    <![CDATA[ Most marketing landing pages start with the same problem: you're staring at a blank screen and rebuilding sections you've already created countless times. A hero section, feature grid, testimonials, p ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-marketing-landing-page-using-shadcn-ui/</link>
                <guid isPermaLink="false">6a6c8095409fd0bcb0afd1c6</guid>
                
                    <category>
                        <![CDATA[ shadcn ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mcp server ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Vaibhav Gupta ]]>
                </dc:creator>
                <pubDate>Fri, 31 Jul 2026 11:01:41 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/82bb4c21-aebe-48c4-9a66-f013011223f4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Most marketing landing pages start with the same problem: you're staring at a blank screen and rebuilding sections you've already created countless times.</p>
<p>A hero section, feature grid, testimonials, pricing, FAQ, and footer are common building blocks, yet developers often spend hours recreating them for every new project.</p>
<p>In this guide, you'll learn how to build a modern marketing landing page using Next.js, shadcn/ui, Tailwind CSS, and reusable Shadcn blocks. Instead of building every section from scratch, you'll assemble a production-ready page, customize it to match your brand, and finish with a foundation that's ready for real-world projects.</p>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ul>
<li><p><a href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a href="#heading-what-are-we-building">What Are We Building?</a></p>
</li>
<li><p><a href="#heading-project-setup-with-base-ui-using-the-shadcn-preset">Project Setup with Base UI Using the Shadcn Preset</a></p>
</li>
<li><p><a href="#heading-two-ways-to-build-your-marketing-landing-page">Two Ways to Build Your Marketing Landing Page</a></p>
</li>
<li><p><a href="#heading-option-1-build-using-the-cli">Option 1: Build Using the CLI</a></p>
</li>
<li><p><a href="#heading-option-2-build-using-the-mcp-server">Option 2: Build Using the MCP Server</a></p>
</li>
<li><p><a href="#heading-how-to-optimize-your-landing-page">How to Optimize Your Landing Page</a></p>
</li>
<li><p><a href="#heading-how-to-expand-your-marketing-website">How to Expand Your Marketing Website</a></p>
</li>
<li><p><a href="#heading-live-preview">Live Preview:</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>Before you start, make sure you have:</p>
<ul>
<li><p>Node.js 18 or higher installed</p>
</li>
<li><p>shadcn/ui initialized in your project (<code>npx shadcn@latest init</code>)</p>
</li>
<li><p>Basic knowledge of React and TypeScript</p>
</li>
</ul>
<p>If you haven't initialized shadcn/ui yet, run <code>npx shadcn@latest init</code> in your project root and follow the prompts before continuing.</p>
<h2 id="heading-what-are-we-building"><strong>What Are We Building?</strong></h2>
<p>In this tutorial, we'll build a modern marketing landing page using production-ready blocks from <a href="https://shadcnspace.com/">Shadcn Space</a>. Instead of designing and developing every section from scratch, we'll assemble a complete landing page using reusable shadcn/ui blocks and customize them to fit our brand and product.</p>
<p>You can use the same approach to create landing pages for SaaS products, AI tools, startups, agencies, developer tools, portfolios, and many other types of websites. Since every block is built with React, Tailwind CSS, and shadcn/ui, you have full control over the code and can easily modify the content, layout, and styling.</p>
<h3 id="heading-why-build-with-shadcn-space">Why Build with Shadcn Space?</h3>
<p>Creating a professional marketing website typically involves designing multiple sections that work together to tell your product's story and guide visitors to take action.</p>
<p>But instead of building every section from scratch, you can start with production-ready blocks that are easy to customize.</p>
<p>This lets you build marketing websites faster with reusable blocks (and you can also mix and match blocks to create unique page layouts). It also gives you full ownership of your clean React and Tailwind CSS code. And overall, you save development time without sacrificing flexibility.</p>
<h3 id="heading-sections-well-build">Sections We'll Build</h3>
<p>We'll build our marketing landing page using the following sections:</p>
<ul>
<li><p>Hero section with a compelling headline, call-to-action, and trusted-by logos.</p>
</li>
<li><p>Features section to highlight your product's key capabilities.</p>
</li>
<li><p>Product Showcase &amp; Benefits section to demonstrate your product and communicate its value.</p>
</li>
<li><p>Testimonials section to build credibility with customer feedback.</p>
</li>
<li><p>Pricing section to present your plans clearly.</p>
</li>
<li><p>FAQ section answers common questions and reduces friction.</p>
</li>
<li><p>Call-to-Action section to encourage visitors to get started.</p>
</li>
<li><p>Footer with navigation and important links.</p>
</li>
</ul>
<h3 id="heading-final-page-structure">Final Page Structure</h3>
<p>Our landing page will have this structure:</p>
<pre><code class="language-javascript">&lt;main&gt;
  {/* 1. Hero section + Trusted by / Logo cloud */}
  &lt;AgencyHeroSection /&gt;

  {/* 2. Features section */}
  &lt;Feature01 /&gt;

  {/* 3. Product showcase &amp; Benefits */}
  &lt;AboutAndStats01 /&gt;

  {/* 4. Testimonials */}
  &lt;Testimonials /&gt;

  {/* 5. Pricing section */}
  &lt;Pricing /&gt;

  {/* 6. FAQ section */}
  &lt;Faq /&gt;

  {/* 7. Call-to-action section */}
  &lt;CTA /&gt;

  {/* Footer */}
  &lt;Footer /&gt;
&lt;/main&gt;
</code></pre>
<p>Each section will be installed from the Shadcn Space registry and customized directly inside our project. By the end of this tutorial, you'll have a fully responsive marketing landing page built with Next.js, Tailwind CSS, and shadcn/ui that you can adapt for your own product or business.</p>
<h2 id="heading-project-setup-with-base-ui-using-the-shadcn-preset"><strong>Project Setup with Base UI Using the Shadcn Preset</strong></h2>
<p>Since Shadcn Space blocks are built using Base UI primitives, we'll create our project using the Base UI preset instead of the default Radix setup.</p>
<p>This ensures that our landing page uses the same foundation as the blocks we're going to install.</p>
<h3 id="heading-1-create-the-project-with-base-ui">1. Create the Project with Base UI</h3>
<p>Run the following command:</p>
<pre><code class="language-javascript">pnpm dlx shadcn@latest init --preset b0 --template next
</code></pre>
<p>This command does a few important things:</p>
<ul>
<li><p>Creates a Next.js project</p>
</li>
<li><p>Configures Tailwind CSS</p>
</li>
<li><p>Sets up Base UI as the component foundation</p>
</li>
<li><p>Uses the Nova style preset</p>
</li>
<li><p>Configures Lucide icons</p>
</li>
<li><p>Uses Inter font</p>
</li>
<li><p>Applies neutral theme tokens</p>
</li>
</ul>
<p>You now have a Base UI-powered Next.js project ready for building your landing page.</p>
<h3 id="heading-2-add-the-shadcn-space-registry">2. Add the Shadcn Space Registry</h3>
<p>Open your <code>components.json</code> and add the following registry configuration:</p>
<pre><code class="language-javascript">{
  "registries": {
    "@shadcn-space": {
      "url": "https://shadcnspace.com/r/{name}.json",
    }
  }
}
</code></pre>
<p>This tells the CLI where to fetch components and blocks from the registry.</p>
<p>For more information about how to use it in your project, <a href="https://shadcnspace.com/docs/getting-started/how-to-use-shadcn-cli">check out the docs</a>.</p>
<h2 id="heading-two-ways-to-build-your-marketing-landing-page"><strong>Two Ways to Build Your Marketing Landing Page</strong></h2>
<p>Now that your project is set up with shadcn/ui, it's time to start building the marketing landing page.</p>
<p>You can install production-ready blocks directly into your project in two different ways:</p>
<ul>
<li><p>Using the CLI</p>
</li>
<li><p>Using the MCP Server inside your AI-powered editor</p>
</li>
</ul>
<p>Both approaches install the actual React and Tailwind CSS source code into your project, giving you complete control over customization. The only difference is how you discover and install the blocks.</p>
<h2 id="heading-option-1-build-using-the-cli">Option 1: Build Using the CLI</h2>
<div class="embed-wrapper"><iframe width="560" height="315" src="https://www.youtube.com/embed/n6dvjVxy02U" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>

<p>The CLI is the fastest way to browse the registry and install individual blocks into your project. It gives you full control over which sections you want to use and how you customize them.</p>
<h3 id="heading-step-1-browse-marketing-blocks">Step 1: Browse Marketing Blocks</h3>
<p>Visit the block registry and explore the available marketing blocks.</p>
<p>Let's review the sections we'll use for this tutorial:</p>
<ul>
<li><p>Hero section with a call-to-action and trusted-by logos</p>
</li>
<li><p>Features section</p>
</li>
<li><p>Product showcase &amp; benefits section</p>
</li>
<li><p>Testimonials section</p>
</li>
<li><p>Pricing section</p>
</li>
<li><p>FAQ section</p>
</li>
<li><p>Call-to-action section</p>
</li>
<li><p>Footer</p>
</li>
</ul>
<p>Choose the blocks that best match the design and style of your website. Since every block is fully customizable, you can easily update the content, colors, spacing, and layout to match your brand.</p>
<p>In the following sections, we'll install each block and customize them.</p>
<h3 id="heading-step-2-install-selected-blocks">Step 2: Install Selected Blocks</h3>
<p>Once you find a block you like, install it using the CLI:</p>
<pre><code class="language-javascript">npx shadcn@latest add @shadcn-space/{block-name}
</code></pre>
<p>Each command downloads the block, places it inside <code>components/shadcn-space/blocks</code>, and installs the required dependencies.</p>
<p>Now your folder might look like this:</p>
<pre><code class="language-javascript">components/
  shadcn-space/
    blocks/
      about-us-section-01/
      hero-01/
      features-01/
      pricing-01/
      testimonial-01/
      faq-01/
      cta-01/
      footer-01/
</code></pre>
<p><strong>Note:</strong> I've used the first block from each section in this tutorial. You can choose any other <a href="https://shadcnspace.com/blocks"><strong>shadcn block</strong></a> that suits best according to your needs.</p>
<h3 id="heading-step-3-add-a-hero-section">Step 3: Add a Hero Section</h3>
<p>Every great marketing landing page starts with a strong hero section. It's the first thing visitors see, so it should clearly communicate what your product does, who it's for, and encourage users to take action.</p>
<p>Instead of building the section from scratch, we'll install a production-ready Hero block and customize it to match our landing page.</p>
<h4 id="heading-1-install-the-hero-block">1. Install the Hero Block</h4>
<p>Run the following CLI command to add the Hero block to your project:</p>
<pre><code class="language-javascript">npx shadcn@latest add @shadcn-space/hero-01
</code></pre>
<p>The CLI will automatically download the Hero block source code, add the component to your project, and install any required dependencies.</p>
<p>After the installation completes, you should see the following directory structure:</p>
<pre><code class="language-javascript">components/
  shadcn-space/
    blocks/
      hero-01/
        index.tsx
</code></pre>
<p>You can now open the component and customize the heading, description, call-to-action buttons, images, and other content to match your product and branding.</p>
<p><strong>2. Understand the Hero Block Structure</strong></p>
<p>Once the installation is complete, open the Hero block located at:</p>
<pre><code class="language-javascript">components/shadcn-space/blocks/hero-01/index.tsx
</code></pre>
<p>You'll see a component similar to the following:</p>
<pre><code class="language-javascript">import HeroSection from "@/components/shadcn-space/blocks/hero-01/hero";
import type { NavigationSection } from "@/components/shadcn-space/blocks/hero-01/header";
import Header from "@/components/shadcn-space/blocks/hero-01/header";
import BrandSlider, { BrandList } from "@/components/shadcn-space/blocks/hero-01/brand-slider";
import type { AvatarList } from "@/components/shadcn-space/blocks/hero-01/hero";

export default function AgencyHeroSection() {
  const avatarList: AvatarList[] = [...];
  const navigationData: NavigationSection[] = [...];
  const brandList: BrandList[] = [...];

  return (
    &lt;div className="relative"&gt;
      &lt;Header navigationData={navigationData} /&gt;
      &lt;main&gt;
        &lt;HeroSection avatarList={avatarList} /&gt;
        &lt;BrandSlider brandList={brandList} /&gt;
      &lt;/main&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p><strong>What Should You Notice?</strong></p>
<p>Before making any changes, take a moment to understand how the block is organized. Rather than being a single large component, it's composed of smaller, reusable components that work together.</p>
<p>In this example:</p>
<ul>
<li><p>The <code>Header</code> component renders the navigation and receives its menu items through the <code>navigationData</code> array.</p>
</li>
<li><p>The <code>HeroSection</code> component contains the main headline, description, call-to-action buttons, and social proof, while the <code>avatarList</code> provides the data displayed in the hero.</p>
</li>
<li><p>The <code>BrandSlider</code> component displays the company logos using the <code>brandList</code> array.</p>
</li>
</ul>
<p>This separation keeps the code modular and makes each part of the landing page easier to customize or replace independently.</p>
<p><strong>Why This Matters?</strong></p>
<p>Because the block is copied directly into your project, you're working with standard React components instead of a compiled package. Every file is fully editable, allowing you to understand how the section is built and modify it to suit your own requirements.</p>
<p>For example, you can update the navigation links, replace the placeholder content with your own branding, add additional sections, integrate custom functionality, or adjust the styling using Tailwind CSS classes. Since everything lives inside your codebase, you're free to restructure the component however you like without being locked into predefined APIs or abstractions.</p>
<h4 id="heading-3-render-the-hero-section">3. Render the Hero Section</h4>
<p>Now that the Hero block has been installed, it's time to display it on the page.</p>
<p>Import the component into your <code>app/page.tsx</code> file:</p>
<pre><code class="language-javascript">import AgencyHeroSection from "@/components/shadcn-space/blocks/hero-01";

export default function Page() {
  return (
    &lt;AgencyHeroSection /&gt;
  );
}
</code></pre>
<p>Save the file and start your development server if it isn't already running. When you open the application in your browser, you'll see the Hero section rendered as the first part of your marketing landing page.</p>
<p>With the Hero section in place, we've completed the first building block of our landing page. Next, we'll continue by adding the remaining sections to create a complete marketing website.</p>
<h3 id="heading-install-the-remaining-blocks">Install the Remaining Blocks</h3>
<p>Now that you've added and rendered the Hero section, let's install the remaining blocks required for our marketing landing page.</p>
<p>Run the following command to install all the remaining sections at once:</p>
<pre><code class="language-javascript">npx shadcn@latest add @shadcn-space/feature-01 @shadcn-space/about-us-section-01 @shadcn-space/testimonial-01 @shadcn-space/pricing-01 @shadcn-space/faq-01 @shadcn-space/cta-01  @shadcn-space/footer-01
</code></pre>
<p><strong>Note:</strong> If you're using Windows Command Prompt or PowerShell, run the command on a single line instead of using <code>\</code> for line continuation.</p>
<p>After the installation is complete, update your <code>app/page.tsx</code> by importing the newly added blocks and rendering them in the following order:</p>
<pre><code class="language-javascript">import AgencyHeroSection from "@/components/shadcn-space/blocks/hero-01";
import AboutAndStats01 from "@/components/shadcn-space/blocks/about-us-01";
import Feature01 from "@/components/shadcn-space/blocks/feature-01";
import Pricing from "@/components/shadcn-space/blocks/pricing-01/pricing";
import Testimonials from "@/components/shadcn-space/blocks/testimonial-01/testimonial";
import Faq from "@/components/shadcn-space/blocks/faq-01/faq";
import CTA from "@/components/shadcn-space/blocks/cta-01/cta";
import Footer from "@/components/shadcn-space/blocks/footer-01/footer";


export const metadata = {
  title: "Acme Agency – Innovative Digital Solutions",
  description:
    "We craft immersive digital experiences for bold brands. Explore our services, pricing, and success stories.",
};


export default function Page() {
  return (
    &lt;main&gt;
      {/* 1. Hero section + Trusted by / logo cloud */}
      &lt;AgencyHeroSection /&gt;


      {/* 2. Features section */}
      &lt;Feature01 /&gt;


      {/* 3. Product showcase &amp; Benefits section (Using About/Stats as a placeholder for these) */}
      &lt;AboutAndStats01 /&gt;


      {/* 4. Testimonials */}
      &lt;Testimonials /&gt;


      {/* 5. Pricing section */}
      &lt;Pricing /&gt;


      {/* 6. FAQ section */}
      &lt;Faq /&gt;


      {/* 7. Call-to-action section */}
      &lt;CTA /&gt;


      {/* Footer */}
      &lt;Footer /&gt;
    &lt;/main&gt;
  );
}
</code></pre>
<p>That's it! Your complete marketing landing page is now assembled. You can start customizing the content, images, colors, and layout of each section to match your product and brand.</p>
<h3 id="heading-customize-the-marketing-landing-page"><strong>Customize the Marketing Landing Page</strong></h3>
<p>At this point, the overall structure of your marketing landing page is complete. The next step is to personalize each section so it reflects your product, brand, and messaging instead of the default placeholder content.</p>
<p>One of the biggest advantages of working with reusable React components is that every section can be customized independently. You can update the content, replace images, adjust layouts, and refine the styling without rebuilding the page from scratch.</p>
<p>The following examples show how the default blocks can be transformed into a polished marketing website.</p>
<p><strong>Customize the Hero Section</strong></p>
<p>The Hero section is the first thing visitors see, so it's the most important place to communicate your product's value. Replace the placeholder headline, supporting text, call-to-action buttons, and trusted brand logos with content that represents your own business.</p>
<p><strong>Before:</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/68b53a3d851476bd2ce87f12/f29da0e0-0da0-482e-bd29-35f3c3c696db.png" alt="Customize the Hero Section Before Using MCP" style="display:block;margin:0 auto" width="1919" height="850" loading="lazy">

<p><strong>After:</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/68b53a3d851476bd2ce87f12/1ec0dad0-0dee-448f-aed2-136e310bbc5b.png" alt="Customize the Hero Section After Using MCP" style="display:block;margin:0 auto" width="1906" height="865" loading="lazy">

<p>Notice how the customized version immediately establishes the product's identity through updated messaging, branding, imagery, and call-to-action buttons.</p>
<p><strong>Customize the Features Section</strong></p>
<p>The Features section should explain what your product offers and why it stands out. Replace the sample feature cards with capabilities that highlight your product's most valuable functionality.</p>
<p><strong>Before:</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/68b53a3d851476bd2ce87f12/b44dfc47-8603-4a1c-847e-b608b84c7723.png" alt="Customize the Features Section Before Using MCP" style="display:block;margin:0 auto" width="1474" height="866" loading="lazy">

<p><strong>After:</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/68b53a3d851476bd2ce87f12/dbc1d529-88ac-42f2-a5d1-0c0348165944.png" alt="Customize the Features Section After Using MCP" style="display:block;margin:0 auto" width="1525" height="936" loading="lazy">

<p>Updating the feature titles, descriptions, and icons makes the section more relevant to your audience while reinforcing your product's key selling points.</p>
<p><strong>Customize the Pricing Section</strong></p>
<p>Your pricing section should clearly communicate the plans you offer and help visitors choose the option that best fits their needs. Replace the default plans, pricing, feature lists, and button labels with information that matches your business model.</p>
<p><strong>Before:</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/68b53a3d851476bd2ce87f12/7e053524-b281-4ee4-9afe-f0ee1ad76d48.png" alt="Customize the Pricing Section Before Using MCP" style="display:block;margin:0 auto" width="1631" height="722" loading="lazy">

<p><strong>After:</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/68b53a3d851476bd2ce87f12/5ae201a8-46a9-4ca4-909c-7e1ecc5c4077.png" alt="Customize the Pricing Section After Using MCP" style="display:block;margin:0 auto" width="1631" height="817" loading="lazy">

<p>A customized pricing section builds trust by presenting accurate information while making it easier for potential customers to compare plans.</p>
<p><strong>Customize the FAQ Section</strong></p>
<p>The FAQ section is a great opportunity to answer common questions before visitors contact your team. Replace the placeholder questions with answers related to your product, pricing, integrations, support, or onboarding process.</p>
<p><strong>Before:</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/68b53a3d851476bd2ce87f12/4b161671-61f0-45c0-8266-3f39015958ec.png" alt="Customize the FAQ Section Before Using MCP" style="display:block;margin:0 auto" width="1650" height="883" loading="lazy">

<p><strong>After:</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/68b53a3d851476bd2ce87f12/8f68f5a8-ad09-4021-843a-58329d0a08ce.png" alt="Customize the FAQ Section After Using MCP" style="display:block;margin:0 auto" width="1638" height="785" loading="lazy">

<p>Tailoring the FAQ to your product helps reduce uncertainty, improves the user experience, and can answer many questions before a customer reaches out.</p>
<p><strong>The Result</strong></p>
<p>With just a few content updates, the default blocks evolve into a professional marketing landing page tailored to your brand. Since every section is built with reusable React components, you can continue refining the design, adjusting layouts, and adding new content as your product grows without changing the overall page structure.</p>
<img src="https://cdn.hashnode.com/uploads/covers/68b53a3d851476bd2ce87f12/3759ae7a-d244-487d-8354-d9dd42570bfd.gif" alt="Full Preview of the Landing Page" style="display:block;margin:0 auto" width="1909" height="840" loading="lazy">

<h2 id="heading-option-2-build-using-the-mcp-server"><strong>Option 2: Build Using the MCP Server</strong></h2>
<div class="embed-wrapper"><iframe width="560" height="315" src="https://www.youtube.com/embed/mMlxAmJlbMI" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>

<p>If you prefer a faster workflow, you can use the MCP Server to generate your landing page directly inside your editor. Instead of manually browsing and installing individual blocks, you simply describe the page you want to build, and the MCP Server assembles an initial version for you.</p>
<p>The MCP Server works with supported editors like Antigravity, VS Code, Cursor, Windsurf, and other MCP-compatible editors.</p>
<h3 id="heading-step-1-install-the-mcp-server">Step 1: Install the MCP Server</h3>
<p><strong>Quick Installation</strong>:</p>
<p>The fastest way to get started. Choose your package manager and run the command corresponding to your client:</p>
<p><strong>For Claude Code</strong>:</p>
<pre><code class="language-javascript">claude mcp add shadcnspace-mcp -- npx -y shadcnspace-mcp@latest
</code></pre>
<p><strong>For Others</strong>:</p>
<pre><code class="language-javascript">npx shadcnspace-cli install &lt;client&gt;
</code></pre>
<p>Replace <code>&lt;client&gt;</code> with <strong>cursor, antigravity, vscode,</strong> or <strong>windsurf</strong>.</p>
<p><strong>Manual Installation For VS Code:</strong></p>
<pre><code class="language-javascript">{
  "servers": {
    "shadcnspace-mcp": {
      "command": "npx",
      "args": ["-y", "shadcnspace-mcp@latest"]
    }
  }
}
</code></pre>
<ul>
<li><p>Open .vscode/mcp.json.</p>
</li>
<li><p>Click Start next to the Shadcn Space MCP server</p>
</li>
</ul>
<p>For a detailed guide, follow the <a href="https://shadcnspace.com/docs/getting-started/mcp-server-docs"><strong>MCP Server documentation</strong></a> to install it for your preferred editor.</p>
<p>Once the installation is complete, restart your editor to enable the MCP connection.</p>
<h3 id="heading-step-2-open-the-ai-chat">Step 2: Open the AI Chat</h3>
<p>Open the AI chat panel inside your editor and describe the landing page you'd like to create.</p>
<p>For example:</p>
<pre><code class="language-javascript">Create a modern marketing landing page for an AI SaaS product.

Use Shadcn Space blocks and include:

- Hero section
- Features section
- Product showcase &amp; benefits
- Testimonials
- Pricing
- FAQ
- Call-to-action
- Footer

Use a clean, modern, and responsive design.
</code></pre>
<p>Feel free to replace the product description with your own and customize as you like.</p>
<h3 id="heading-step-3-generate-the-landing-page">Step 3: Generate the Landing Page</h3>
<p>After receiving your prompt, the MCP Server analyzes your requirements and selects the most suitable blocks for your landing page. It automatically assembles the page using a combination of reusable sections, giving you a working layout in just a few moments.</p>
<p>The generated sections are added directly to your project as standard React components. Since everything is real source code, you can customize every part of the page: update the content, replace images, modify the layout, adjust spacing, or restyle components using Tailwind CSS.</p>
<p>The MCP Server simply speeds up the initial setup, while giving you complete control over the final implementation.</p>
<img src="https://cdn.hashnode.com/uploads/covers/68b53a3d851476bd2ce87f12/2247726d-12ab-47d8-bd7a-49b025ea0eb5.gif" alt="How to Generate the Landing Page" style="display:block;margin:0 auto" width="1909" height="913" loading="lazy">

<h2 id="heading-how-to-optimize-your-landing-page">How to Optimize Your Landing Page</h2>
<p>Building a visually appealing landing page is only the first step. Before publishing your website, it's worth spending some time optimizing it for performance, search engines, and user experience.</p>
<p>A fast, responsive landing page not only feels more polished but also helps improve engagement and conversion rates. Fortunately, Next.js provides several built-in features that make these optimizations straightforward.</p>
<h3 id="heading-optimize-images-with-nextjs">Optimize Images with Next.js</h3>
<p>Images are often the largest assets on a marketing website, so optimizing them can significantly improve loading performance. If you're using Next.js, prefer the built-in <code>next/image</code> component instead of the standard HTML image tag. It automatically serves appropriately sized images, supports modern image formats, and reduces layout shifts as the page loads.</p>
<p>Before adding screenshots or illustrations to your project, make sure they're compressed and sized appropriately. Well-optimized images create a smoother browsing experience across desktop and mobile devices while also contributing to better Core Web Vitals.</p>
<h3 id="heading-improve-seo-for-your-landing-page">Improve SEO for Your Landing Page</h3>
<p>A well-designed landing page is only effective if people can discover it. Search engine optimization starts with creating meaningful content that clearly communicates what your product offers. Choose a descriptive page title, write a concise meta description, and organize your content using logical headings.</p>
<p>Your primary keyword should appear naturally throughout the page without forcing it into every paragraph. Focus on writing for your audience first, then structure the content in a way that search engines can easily understand. Combining valuable content with a clear page hierarchy gives your landing page the best chance of ranking for relevant searches.</p>
<h3 id="heading-add-metadata-and-open-graph-images">Add Metadata and Open Graph Images</h3>
<p>When someone shares your landing page on social media or in a messaging application, the preview is generated from your page's metadata. Configuring Open Graph and Twitter metadata allows you to control the title, description, and preview image that appear when your website is shared.</p>
<p>A custom preview image that reflects your branding makes your links look more professional and can encourage more people to click through. Taking a few minutes to configure these settings helps create a more polished experience whenever your content is shared online.</p>
<h3 id="heading-optimize-performance">Optimize Performance</h3>
<p>Performance plays a major role in how visitors perceive your website. A page that loads quickly feels more responsive and encourages users to continue exploring your content. As you customize your landing page, keep unnecessary JavaScript to a minimum, optimize static assets, and avoid loading resources that aren't immediately needed.</p>
<p>Even small improvements, such as reducing image sizes or simplifying animations, can noticeably improve loading speed. Before deploying your project, test the page under different network conditions to ensure it performs well for all visitors.</p>
<h3 id="heading-improve-core-web-vitals">Improve Core Web Vitals</h3>
<p>Core Web Vitals are Google's metrics for measuring real-world user experience. They evaluate how quickly your main content appears, how responsive the page feels during interactions, and whether elements remain stable as the page loads. Monitoring these metrics throughout development helps identify potential issues before they affect users.</p>
<p>Tools such as Lighthouse and PageSpeed Insights provide detailed reports that can help you improve loading performance and responsiveness. A landing page with strong Core Web Vitals not only creates a better experience for visitors but can also contribute to improved search rankings.</p>
<hr>
<h2 id="heading-how-to-expand-your-marketing-website"><strong>How to Expand Your Marketing Website</strong></h2>
<p>A landing page is often just the beginning of a complete marketing website. As your product grows, you'll likely need additional pages that provide more information, improve navigation, and create a better experience for your visitors. Common additions include Blog, Blog Details, Pricing, FAQ, Changelog, Contact, Integration, Error, and About Us pages.</p>
<p>Building these pages with a consistent design system helps maintain a unified look and feel across your entire website while reducing development time. Reusing layouts and components also makes your project easier to maintain as it evolves.</p>
<p>If you're looking to expand your website beyond a single landing page, explore the collection of production-ready <a href="https://shadcnspace.com/pages"><strong>Shadcn website pages</strong></a>, built with React, Next.js, Tailwind CSS, and shadcn/ui.</p>
<h2 id="heading-live-preview"><strong>Live Preview:</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/68b53a3d851476bd2ce87f12/a189f09d-550d-4c7f-b20a-477f5bc1bfa0.gif" alt="How to Expand Your Marketing Website" style="display:block;margin:0 auto" width="1909" height="913" loading="lazy">

<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>In this tutorial, we built a complete marketing landing page using Next.js, shadcn/ui, Tailwind CSS, and reusable Shadcn Space blocks. Starting from a fresh project, we assembled a production-ready page by combining sections such as the Hero, Features, Product Showcase, Testimonials, Pricing, FAQ, Call-to-Action, and Footer.</p>
<p>Because every block is added as standard React source code, you're free to customize the content, layout, styling, and functionality to match your own product and branding. Whether you're building a SaaS application, a startup website, an AI product, an agency site, or a developer tool, the same approach can be adapted to your requirements.</p>
<p>A marketing landing page is just the foundation of your online presence. As your product grows, you can continue expanding your website with additional marketing pages while maintaining a consistent design system and development workflow.</p>
<p>I hope this guide has helped you understand how to quickly build a modern, responsive marketing landing page using reusable components. Feel free to experiment with different block combinations, personalize the design, and create a website that best represents your product.</p>
<p><strong>Appreciation</strong>: I wrote this article with the help of Mihir Koshti (Sr. Full Stack Developer) – <a href="https://www.linkedin.com/in/mihir-koshti/">Connect on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Why Front-End Developers Should Understand UI/UX Design ]]>
                </title>
                <description>
                    <![CDATA[ When users interact with a website or application, the first thing they notice isn’t the code. Instead, it’s the design and experience. Smooth navigation, intuitive layouts, and visually appealing interfaces are what keep users engaged. Behind these ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/why-front-end-developers-should-understand-uiux-design/</link>
                <guid isPermaLink="false">68c4087abba5a7e638ae4cd6</guid>
                
                    <category>
                        <![CDATA[ Frontend Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI UX ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Asfak Ahmed ]]>
                </dc:creator>
                <pubDate>Fri, 12 Sep 2025 11:48:10 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1757677089930/07115f35-ba9e-452a-bf95-3a96de7a5d24.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When users interact with a website or application, the first thing they notice isn’t the code. Instead, it’s the design and experience. Smooth navigation, intuitive layouts, and visually appealing interfaces are what keep users engaged.</p>
<p>Behind these experiences, front-end developers play a pivotal role. They don’t just turn mockups into functioning code – they shape the bridge between design and functionality, making user experiences come to life.</p>
<p>To do this effectively, front-end developers need to understand UI (User Interface) and UX (User Experience) design.</p>
<ul>
<li><p><strong>UI</strong> focuses on the look and feel of the product, including colors, typography, buttons, layouts, and visual consistency.</p>
</li>
<li><p><strong>UX</strong> focuses on how users interact with the product, including ease of use, accessibility, responsiveness, and overall satisfaction.</p>
</li>
</ul>
<p>In today’s competitive digital landscape, knowing only code isn’t enough. Let’s explore why UI/UX knowledge is crucial for front-end developers and how it impacts both the developer’s career and the end-user experience.</p>
<h2 id="heading-table-of-contents"><strong>Table of Content</strong>s:</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-why-front-end-devs-should-understand-uxui">Why Front-End Devs Should Understand UX/UI</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-key-uiux-principles-every-front-end-developer-should-know">Key UI/UX Principles Every Front-End Developer Should Know</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-benefits-of-uiux-knowledge-for-front-end-developers">Benefits of UI/UX Knowledge for Front-End Developers</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-developers-can-learn-uiux">How Developers Can Learn UI/UX</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-to-keep-in-mind-about-uxui">What to Keep in Mind about UX/UI</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-why-front-end-devs-should-understand-uxui">Why Front-End Devs Should Understand UX/UI</h2>
<p>Front-end development is not just about writing clean code. It’s also about creating experiences. A developer might know every JavaScript framework and CSS trick, but if they don’t understand UI (User Interface) and UX (User Experience) principles, their work risks feeling clunky, confusing, or unappealing.</p>
<h3 id="heading-why-uiux-knowledge-matters">Why UI/UX Knowledge Matters</h3>
<ol>
<li><p><strong>Bridging the gap between design and development:</strong> Front-end developers act as the bridge between design mockups and functional applications. By understanding UI/UX principles, developers can implement designs more accurately, while also identifying potential improvements in usability or accessibility.</p>
</li>
<li><p><strong>Improving usability:</strong> UI/UX knowledge helps developers think beyond visuals. They consider user flow, navigation, responsiveness, and accessibility. For example, a button’s size, contrast, and placement affect how easily users interact with it.</p>
</li>
<li><p><strong>Creating consistent experiences:</strong> Without consistency, users get frustrated. Developers who understand design systems and UX patterns ensure that spacing, typography, colors, and interactions feel uniform across the app.</p>
</li>
<li><p><strong>Boosting collaboration with designers:</strong> Developers who know UI/UX can speak the same language as designers. This leads to smoother handoffs, fewer revisions, and faster delivery. Instead of just “coding what’s given,” they can proactively suggest alternatives when something won’t scale well.</p>
</li>
<li><p><strong>Improving user satisfaction and business goals:</strong> Ultimately, great UI/UX translates to happy users. An application that is visually appealing, easy to navigate, and responsive encourages engagement, reduces bounce rates, and drives conversions.</p>
</li>
</ol>
<h2 id="heading-key-uiux-principles-every-front-end-developer-should-know">Key UI/UX Principles Every Front-End Developer Should Know</h2>
<p>A website or application may be powered by complex logic in the background, but what users truly experience is the interface. This is where understanding UI/UX principles becomes essential. Let’s explore some of the core ideas every developer should master.</p>
<h3 id="heading-consistency-builds-trust">Consistency Builds Trust</h3>
<p>One of the most fundamental principles of good UI/UX is consistency. When layouts, typography, buttons, and navigation behave the same way across an application, users instantly feel more confident.</p>
<p>Imagine a scenario where a “Sign Up” button looks completely different on each page – one rounded, another outlined, another square. This inconsistency doesn’t just look unprofessional, it breaks trust and forces users to pause and think. A consistent interface, on the other hand, feels reliable and predictable.</p>
<p><strong>Example:</strong></p>
<p>The image below compares two sets of buttons to highlight the importance of design consistency. On the left, the "Consistent Buttons" example shows "Sign Up" and "Login" buttons that look identical in color, shape, and style, making the user interface appear clear and professional. On the right, the "Inconsistent Buttons" example displays the same buttons but with different colors, shapes, and text styles, which can make the interface confusing and visually unappealing.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757048948178/8d74c12b-f1ac-442a-81e5-906c5b0dce2c.png" alt="Consistency Builds Trust example image" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-guiding-users-with-visual-hierarchy">Guiding Users with Visual Hierarchy</h3>
<p>Users rarely read web pages word by word. Instead, they scan for what matters. That’s why visual hierarchy is so important. By adjusting size, contrast, color, and spacing, developers can subtly guide attention. Headlines should naturally stand out from body text, and primary actions like “Buy Now” or “Sign Up” should be visually stronger than secondary options.</p>
<p>A great example of this is a pricing page where the recommended plan is highlighted with a brighter color and a slightly larger card, drawing the eye instantly.</p>
<p><strong>Example:</strong></p>
<p>The image below shows three pricing plans Base, Pro, and Enterprise, with the Pro plan visually highlighted in the center. The design uses size, color contrast, and placement to guide users attention toward the Pro plan, illustrating the concept of visual hierarchy for easier decision-making.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757049059813/a2363890-44f6-4394-b307-db62fd3b38b0.png" alt="Guiding Users with Visual Hierarchy example image" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-accessibility-for-everyone">Accessibility for Everyone</h3>
<p>A beautiful interface is meaningless if it’s not usable by all. <a target="_blank" href="https://www.freecodecamp.org/news/why-accessibility-matters-in-ui-ux-design/">Accessibility</a> ensures that people with disabilities can interact with your site just as easily as others. This means paying attention to color contrast so text remains readable, using semantic HTML so screen readers can interpret content, and adding descriptive alt text to images.</p>
<p>Even small improvements – like ensuring forms have proper labels – can transform usability. A login form without labels may look clean, but it excludes users who rely on assistive technology.</p>
<p><strong>Example:</strong></p>
<p>The picture below compares two login forms to show the difference between poor and good form design. The "Bad Form" on the left lacks clear labels for its input fields and has a dull, hard-to-see login button, making it less user-friendly. The "Good Form" on the right uses visible labels for each field and a prominent, easy-to-find login button, which improves clarity and usability for users.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757049101402/de1a3424-d599-4243-b760-a9114b9d99f0.png" alt="Accessibility for Everyone example image" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-designing-for-all-screens">Designing for All Screens</h3>
<p>With most traffic now coming from mobile devices, responsive design is no longer optional. A layout that looks perfect on desktop but breaks on mobile will drive users away.</p>
<p>Mobile-first thinking encourages developers to start small and then expand layouts for larger screens. This ensures that buttons are touch-friendly, text remains readable, and navigation adapts naturally. A dashboard that stacks neatly into a single column on mobile but expands gracefully on desktop provides a consistent experience everywhere.</p>
<p><strong>Example:</strong></p>
<p>The image below shows how pricing plans are tailored for various screen sizes. On the left, the "Desktop Design" displays multiple plans side by side, allowing easy comparison. On the right, the "Mobile Design" stacks the plans vertically, making them easy to read and navigate on smaller screens.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757049871365/4a5b8bfb-5a83-415b-9ec2-55802abb9fb9.png" alt="Designing for All Screens example image" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-clear-feedback-and-interaction">Clear Feedback and Interaction</h3>
<p>Users should never be left guessing. Every interaction must provide feedback – whether that’s a hover animation on a button, a loading indicator when submitting a form, or a success/error message after an action.</p>
<p>Consider a “Submit” button: if it does nothing after being clicked, the user may think the site is broken. But if it shows a spinner followed by a success message, the experience feels reassuring and complete.</p>
<p><strong>Example:</strong></p>
<p>The gif below demonstrates clear user feedback during a button interaction. When the "Submit" button is clicked, a loading spinner appears to show that the action is being processed, followed by a success message once the process is complete. This ensures users know their action is registered and provides reassurance, preventing confusion or uncertainty.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757076411317/42e940e9-cf3d-4155-be43-94217f135468.gif" alt="Clear Feedback and Interaction example gif video" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-designing-with-the-user-in-mind">Designing with the User in Mind</h3>
<p>At the heart of UI/UX is empathy. A developer must always ask: “Is this intuitive for someone seeing it or using it for the first time?”</p>
<p>Placing the search bar at the top of a page makes sense because that’s where users expect it. Hiding it deep inside a menu might seem clever, but it often frustrates users. The best interfaces are designed around user expectations, not developer preferences.</p>
<p><strong>Example:</strong></p>
<p>The GIF image below demonstrates the impact of user-centered design in UI/UX. The "Good UX" example places the search bar at the top of the page, making it immediately visible and easy for users to find. In contrast, the "Bad UX" example hides the search bar inside a menu, which makes it harder to access and can frustrate users.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757076951279/47559d0f-7603-457f-be8f-f99797cf6ade.gif" alt="Designing with the User in Mind example gif video" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-benefits-of-uiux-knowledge-for-front-end-developers">Benefits of UI/UX Knowledge for Front-End Developers</h2>
<p>Front-end developers often see themselves as the builders, the ones who transform design files into functional web pages and applications. But those who also understand UI and UX principles unlock a significant advantage. Their work doesn’t just “look like the design” – it feels intuitive, efficient, and enjoyable for the end user.</p>
<h3 id="heading-bridging-the-gap-between-design-and-code">Bridging the Gap Between Design and Code</h3>
<p>Designers create mockups with a vision in mind, but many of those details get lost when moving into code. A developer with UI/UX knowledge understands why spacing is generous, why a button changes color on hover, or <em>why</em> a particular layout improves navigation.</p>
<p>Instead of copying pixels mechanically, they preserve the intent of the design. Without this understanding, designs may look “close enough” but feel awkward in practice.</p>
<p><strong>Example:</strong></p>
<p>The image below compares bad versus good UI design. The left side shows a messy header with mismatched buttons that have different shapes, sizes, and colors, demonstrating poor design consistency. The right side shows the same header redesigned properly with uniform blue buttons that are consistently sized and aligned, creating a much cleaner and more professional appearance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757050797636/a9559e8b-ef9e-4aa9-9c79-08b1a986e0a2.png" alt="Bridging the Gap Between Design and Code example imge" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-building-for-usability-not-just-functionality">Building for Usability, Not Just Functionality</h3>
<p>Functionality answers the question: <em>Does this work?</em> Usability asks: <em>Does this feel natural to use?</em> Developers who understand UI/UX instinctively add helpful touches like loading indicators, clear error messages, and accessible labels.</p>
<p>Without this mindset, users encounter confusing flows, tiny buttons, hidden actions, or forms with no feedback. The product works, technically, but it doesn’t <em>work well.</em></p>
<p><strong>Example:</strong></p>
<p>The image below shows a login form comparison between poor and improved UX design. The left side demonstrates bad UX with empty input fields that have no placeholder text, a bland gray login button, and unclear help text that says "Forgot password? Not obvious." The right side shows the improved version with helpful placeholder text like "Enter your email" and "Enter your password," a prominent blue login button that's more visually appealing, and clearer, actionable help text that says "Forgot password? Click here to reset."</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757050840166/34aacf33-3dec-446f-bada-22b8a9c14f2d.png" alt="Building for Usability, Not Just Functionality example image" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-faster-collaboration-and-fewer-iterations">Faster Collaboration and Fewer Iterations</h3>
<p>When developers understand design language, they can talk specifics, “The spacing here should follow the 8px grid,” instead of vague complaints like “This looks off.” This cuts down on revisions, keeps teams aligned, and builds trust between designers and developers.</p>
<p>Without this shared language, collaboration slows. Misinterpretations multiply, feedback loops drag on, and projects risk missing deadlines.</p>
<h3 id="heading-stronger-problem-solving-and-adaptability">Stronger Problem-Solving and Adaptability</h3>
<p>Projects rarely stick to the original plan. Edge cases and new requirements always emerge. Developers with UI/UX insight can make smart, user-centered choices on the fly, selecting layouts, typography scales, or navigation patterns that enhance the experience.</p>
<p>Without this knowledge, fixes tend to be purely technical, functional, but clunky, leaving users to struggle through awkward flows.</p>
<p><strong>Example:</strong></p>
<p>The image below demonstrates dashboard navigation design. The left side shows a "Cluttered Dashboard" with nine separate menu items scattered randomly (Users, Settings, Reports, Analytics, Notifications, Billing, Integrations, Logs, Support), making it overwhelming and difficult to navigate. The right side shows a "UX-Improved Dashboard" that organizes the same options into three logical categories: "User Management" (Users, Roles), "Settings" (General, Billing, Integrations), and "Analytics &amp; Support" (Reports, Analytics, Support). The improved version reduces cognitive load by grouping related functions, making the interface much easier to understand and navigate.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757050891751/50920984-c330-40b3-957b-6b56b18eaea0.png" alt="Enhancing Problem-Solving Skills example image" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-competitive-and-professional-advantage">Competitive and Professional Advantage</h3>
<p>In today’s job market, many developers can code a responsive layout. What makes someone stand out is their ability to think about both aesthetics and usability. Employers and clients value these hybrid professionals who bridge two traditionally separate worlds.</p>
<p>Without UI/UX awareness, developers risk blending into the crowd. Their work may be solid, but it lacks the polish and empathy that win user trust and give products a competitive edge.</p>
<h3 id="heading-missed-opportunities-for-user-trust">Missed Opportunities for User Trust</h3>
<p>Users form judgments about applications within seconds. If the interface looks clunky or confusing, it signals to them that the product may not be reliable. Developers who overlook UI/UX miss this psychological layer of trust. An intuitive, visually consistent interface not only helps users accomplish their tasks but also assures them that the product is worth relying on.</p>
<p><strong>Without UI/UX, developers often:</strong></p>
<ul>
<li><p>Push out features that confuse rather than guide.</p>
</li>
<li><p>Create inconsistent layouts that erode confidence.</p>
</li>
<li><p>Overwhelm users with unnecessary complexity.</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<p>The image below illustrates how UI/UX design affects user trust. The left side shows "Missed Trust" with a poorly designed interface that has inconsistent styling - a basic input field, a small gray "Continue" button, and a confusing pink "Next Step?" button that creates uncertainty about what action to take. The right side shows "Built for Trust" with a clean, professional design featuring a well-styled input field with placeholder text and a prominent, clear "Continue" button that gives users confidence in their actions.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757152308435/754f5bf3-0fa0-4bf4-b725-634516fbe487.png" alt="Missed Opportunities for User Trust example image" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-inclusivity-and-accessibility">Inclusivity and Accessibility</h3>
<p>Accessibility is a core part of good UX. Developers with this awareness naturally consider screen reader support, keyboard navigation, and high-contrast modes. This ensures products welcome <em>all</em> users.</p>
<p>Without it, developers unintentionally exclude large groups of people and may even face compliance issues. The result isn’t just a less usable product, it fails to respect and include its audience.</p>
<h2 id="heading-how-developers-can-learn-uiux">How Developers Can Learn UI/UX</h2>
<p>For a long time, developers and designers were seen as working on two separate islands. Developers wrote code, designers crafted interfaces, and the two worlds met somewhere in the middle. But today, the line is much blurrier. Employers and teams increasingly expect developers to have at least a foundational understanding of UI/UX.</p>
<p>The good news is that UI/UX isn’t a mysterious art that only designers can master. Developers can learn it step by step, much like they learned programming languages or frameworks. It requires observation, practice, and empathy for the end user.</p>
<h3 id="heading-start-with-observation">Start with Observation</h3>
<p>One of the simplest ways to begin learning UI/UX is by observing products you already use every day. Pay attention to how you navigate your favorite apps or websites. Notice how buttons are placed, how forms are structured, or how feedback is given when you complete an action. Ask yourself: <em>Why does this feel easy to use? Why does this frustrate me?</em></p>
<p>Observation builds awareness. Once you start noticing design decisions in your daily digital life, you’ll begin to understand the invisible rules that shape user experiences.</p>
<h3 id="heading-understand-the-basics-of-ux-principles">Understand the Basics of UX Principles</h3>
<p>Before diving deep, you should familiarize yourself with some core UX principles. These aren’t abstract theories but practical guidelines for making products usable. To review them:</p>
<ul>
<li><p><strong>Consistency</strong>: Users expect familiar patterns. A back button should always go back, not do something unpredictable.</p>
</li>
<li><p><strong>Clarity</strong>: Every element should serve a purpose. If it confuses, it doesn’t belong.</p>
</li>
<li><p><strong>Feedback</strong>: Users need to know when an action has been registered, whether it’s a loading spinner, a success message, or an error prompt.</p>
</li>
<li><p><strong>Accessibility</strong>: Interfaces should be usable by everyone, including people with disabilities.</p>
</li>
</ul>
<p>Learning these basics gives you a strong foundation for evaluating and improving your work.</p>
<h3 id="heading-practice-through-side-projects">Practice Through Side Projects</h3>
<p>Theory alone won’t help – as a dev, you need to practice. A simple way to start is by taking small side projects and focusing not just on functionality but also on experience. Build a to-do app, for instance, but pay attention to how tasks are added, how the interface responds, and how information is displayed.</p>
<p>Treat each project as a learning ground for experimenting with usability, not just coding. You’ll begin to notice where users get stuck and how small tweaks can create big improvements.</p>
<h3 id="heading-learn-design-tools-but-dont-get-overwhelmed">Learn Design Tools, But Don’t Get Overwhelmed</h3>
<p>You don’t need to become a master of Figma or Sketch overnight, but learning the basics of design tools can help you bridge the gap between development and design. Being able to open a Figma file, understand layout grids, or inspect spacing gives you a significant advantage when collaborating with designers.</p>
<p>The goal isn’t to replace designers but to communicate better with them and reduce misinterpretations.</p>
<h3 id="heading-follow-real-world-uiux-examples">Follow Real-World UI/UX Examples</h3>
<p>Another powerful way to learn is by studying existing products. Look at how popular apps like Spotify, Airbnb, or Notion structure their interfaces. Read UX case studies where designers explain their decisions. These real-world examples give context to abstract principles and help developers see how theory translates into practice.</p>
<h3 id="heading-seek-feedback-from-designers-and-users">Seek Feedback from Designers and Users</h3>
<p>Learning UI/UX isn’t just about self-study. It’s also about listening. Share your projects with others, especially designers or actual users, and ask for feedback. What felt easy? What was confusing? As a developer, you may overlook usability issues because you’re too close to the code. External feedback helps you see the product with fresh eyes.</p>
<h3 id="heading-build-empathy-through-testing">Build Empathy Through Testing</h3>
<p>Nothing teaches UI/UX faster than watching someone use your product. Conduct informal usability tests with friends, colleagues, or even strangers. Observe where they hesitate, where they click instinctively, and where they get frustrated. This direct exposure helps developers understand that design isn’t just about what looks good, it’s about what feels natural in practice.</p>
<h3 id="heading-keep-learning-from-design-communities">Keep Learning from Design Communities</h3>
<p>UI/UX is a constantly evolving field. You can grow by engaging with design communities, reading blogs, or following design challenges. Platforms like Dribbble, Behance, and UX Collective provide inspiration and practical lessons. Over time, this exposure sharpens your design instincts and keeps you aligned with industry trends.</p>
<h3 id="heading-some-helpful-resources-to-learn-uiux">Some Helpful Resources to Learn UI/UX:</h3>
<p>📚 <strong>Books:</strong></p>
<ul>
<li><p><strong>Refactoring UI (Adam Wathan &amp; Steve Schoger)</strong>: <a target="_blank" href="https://refactoringui.com/book">https://refactoringui.com/book</a> (I’ve read this book, and the feedback is awesome)</p>
</li>
<li><p><strong>The Design of Everyday Things (Don Norman)</strong>: <a target="_blank" href="https://jnd.org/the-design-of-everyday-things/">https://jnd.org/the-design-of-everyday-things/</a></p>
</li>
<li><p><strong>Laws of UX (Jon Yablonski)</strong>: <a target="_blank" href="https://lawsofux.com/">https://lawsofux.com/</a></p>
</li>
</ul>
<p><strong>🌐 Blogs &amp; Guides:</strong></p>
<ul>
<li><p><strong>Smashing Magazine</strong>: <a target="_blank" href="https://www.smashingmagazine.com/category/uxdesign/">https://www.smashingmagazine.com/category/uxdesign/</a></p>
</li>
<li><p><strong>UX/UI Design Tutorial</strong>: <a target="_blank" href="https://www.freecodecamp.org/news/ui-ux-design-tutorial-from-zero-to-hero-with-wireframe-prototype-figma/">https://www.freecodecamp.org/news/ui-ux-design-tutorial-from-zero-to-hero-with-wireframe-prototype-figma/</a></p>
</li>
<li><p><strong>UX Collective</strong>: <a target="_blank" href="https://uxdesign.cc/">https://uxdesign.cc/</a></p>
</li>
<li><p><strong>Nielsen Norman Group (NNG)</strong>: <a target="_blank" href="https://www.nngroup.com/articles/">https://www.nngroup.com/articles/</a></p>
</li>
</ul>
<p>🎥 <strong>YouTube:</strong></p>
<ul>
<li><p><strong>DesignCourse (Gary Simon)</strong>: <a target="_blank" href="https://www.youtube.com/c/DesignCourse">https://www.youtube.com/c/DesignCourse</a></p>
</li>
<li><p><strong>Flux Academy</strong>: <a target="_blank" href="https://www.youtube.com/c/FluxWithRanSegall">https://www.youtube.com/c/FluxWithRanSegall</a></p>
</li>
<li><p><strong>Steve Schoger (Design Tips)</strong>: <a target="_blank" href="https://www.youtube.com/c/SteveSchoger">https://www.youtube.com/c/SteveSchoger</a></p>
</li>
<li><p><strong>Kevin Powell</strong>: <a target="_blank" href="https://www.youtube.com/kepowob">https://www.youtube.com/kepowob</a></p>
</li>
</ul>
<p><strong>🛠️ Tools &amp; Practice:</strong></p>
<ul>
<li><p><strong>Figma</strong>: <a target="_blank" href="https://www.figma.com/">https://www.figma.com/</a></p>
</li>
<li><p><strong>Dribbble</strong>: <a target="_blank" href="https://dribbble.com/">https://dribbble.com/</a></p>
</li>
<li><p><strong>Behance:</strong> <a target="_blank" href="https://www.behance.net/">https://www.behance.net/</a></p>
</li>
<li><p><strong>Mobbin</strong>: <a target="_blank" href="https://mobbin.com/">https://mobbin.com/</a></p>
</li>
</ul>
<h2 id="heading-what-to-keep-in-mind-about-uxui">What to Keep in Mind about UX/UI</h2>
<p>Some of these tips might feel counterintuitive to anyone who lives in code all day. Yet they explain why users behave the way they do, and why some products succeed where others fail. Here are some of the weird but true things about UI/UX that every developer should know.</p>
<h3 id="heading-users-rarely-read-they-scan">Users Rarely Read. They Scan….</h3>
<p>You may spend hours ensuring error messages, tooltips, or onboarding text are written clearly. But here’s the strange reality: most users don’t actually <em>read</em> them. They scan. Their eyes dart across headings, buttons, and visuals, often skipping over entire paragraphs.</p>
<p>This means your beautifully worded instructions may never be read. Instead, design needs to be built around <strong>visual cues and intuitive flows</strong> that guide users without relying on text.</p>
<p><strong>Example:</strong></p>
<p>The image contrasts verbose versus concise user instructions. The left side shows "Wordy Instructions" with a lengthy paragraph that overwhelms users with unnecessary details about clicking settings, navigating tabs, selecting preferences, and remembering to save changes. The right side demonstrates "Quick Setup" with a clean, numbered three-step process: "1. Open Settings, 2. Choose Preferences, 3. Click Save" followed by a clear "Save &amp; Continue" button. The improved version eliminates cognitive overload by presenting the same information in a scannable, actionable format that's much easier for users to follow and complete successfully.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757151919813/47bb5556-954d-43f0-ba10-98c9ebedcb7a.png" alt="Users Rarely Read. They Scan example image" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-a-buttons-size-can-outweigh-its-functionality">A Button’s Size Can Outweigh Its Functionality</h3>
<p>From a developer’s perspective, a button either triggers a function or it doesn’t. But in UX, the <strong>size, placement, and color</strong> of that button can matter more than the functionality behind it.</p>
<p>For example, two buttons may perform the same action, but if one is too small, hidden, or styled poorly, users might not notice it at all. The function exists in code, but in practice, it doesn’t exist for the user.</p>
<p><strong>Example:</strong></p>
<p>The image shows how button size and design affect usability. The left side has a small, gray "Save" button that's hard to notice and might be missed by users. The right side has the same "Save" button but larger, darker, and more prominent, making it much more likely that users will see and click it. Same function, but better design leads to better user interaction.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757151978289/c347439c-004a-4ca4-9a8c-8528ca48bc4c.png" alt="A Button’s Size Can Outweigh Its Functionality example image" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-more-features-often-mean-less-usability">More Features Often Mean Less Usability</h3>
<p>It feels logical to think that giving users more options and features adds value. But weirdly, the opposite is often true. The more you add, the harder the product becomes to use.</p>
<p>This is called the <strong>paradox of choice</strong>: too many options create decision fatigue. Developers love shipping features, but good UX often means stripping things away until only the essentials remain.</p>
<h3 id="heading-ugly-designs-sometimes-work-better">“Ugly” Designs Sometimes Work Better</h3>
<p>Developers may assume a slick, modern UI always wins, but there are cases where “ugly” or “dated” designs perform better because they feel familiar and trustworthy. Think of Craigslist: it hasn’t changed much in decades, but people use it because it feels simple. This shows that usability can beat aesthetics when it comes to building trust.</p>
<p><strong>Example:</strong></p>
<p>The image illustrates that modern aesthetics don't always equal better usability. The left side shows a "Modern &amp; Slick" design with a sleek, dark "Explore" button that looks impressive and cutting-edge but might feel unfamiliar or untrustworthy to some users. The right side shows an "Old-School &amp; Familiar" design with a simple gray "Continue" button that appears outdated but feels trustworthy and familiar to users.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757152055106/b01d0abd-ef1a-42ac-9670-00601f27ef10.png" alt="“Ugly” Designs Sometimes Work Better example image" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-users-dont-think-like-developers">Users Don’t Think Like Developers</h3>
<p>This might be the weirdest truth of all: users don’t care about code efficiency, data structures, or the elegant architecture behind the app. They only care about what’s on their screen and whether it makes sense.</p>
<p>For example, a developer might proudly optimize a search algorithm, but if the search bar is hidden in a menu instead of being front and center, users will complain that “the app doesn’t have search.” The feature exists, but in their minds, it doesn’t.</p>
<p><strong>Example:</strong></p>
<p>The GIF image demonstrates the impact of user-centered design in UI/UX. The "Good UX" example places the search bar at the top of the page, making it immediately visible and easy for users to find. In contrast, the "Bad UX" example hides the search bar inside a menu, which makes it harder to access and can frustrate users.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757076951279/47559d0f-7603-457f-be8f-f99797cf6ade.gif" alt="Users Don’t Think Like Developers example gif video" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-small-delays-feel-bigger-than-they-are">Small Delays Feel Bigger Than They Are</h3>
<p>From a technical side, shaving 300 milliseconds off a request may not feel like a huge deal. But to a user, even slight delays feel magnified. A loading spinner that lingers for a second can feel like forever. UX research shows that anything beyond 2–3 seconds risks losing the user’s attention.</p>
<p>This means developers must think not only about raw performance but also about perceived performance using skeleton screens, micro-animations, or progress indicators to make waits feel shorter.</p>
<p><strong>Example:</strong></p>
<p>The image compares the loading experience design. The left side shows "Feels Slow" with just a basic spinner and "Loading..." text that makes even short delays feel endless to users. The right side shows "Feels Faster" using skeleton screens - gray placeholder blocks that mimic the content structure while loading, making the same delay feel much shorter because users can see that progress is happening and get a preview of what's coming.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757152098385/a764127e-7a34-4ac8-b04b-444f911b40b4.png" alt="Small Delays Feel Bigger Than They Are example image" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-accessibility-isnt-just-for-some-users">Accessibility Isn’t Just for “Some” Users</h3>
<p>Developers sometimes assume accessibility features (like screen reader support, keyboard navigation, or high-contrast modes) are niche concerns. But here’s the reality: everyone benefits.</p>
<p>Captions help people in noisy environments, large touch targets help on small screens, and good color contrast improves readability for everyone. Accessibility isn’t just about inclusivity – it’s about creating universally better experiences.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In modern web development, understanding UI/UX isn’t optional. It’s essential. Front-end developers aren’t just programmers – they are the architects of user experience. By learning design principles, developers improve collaboration, write smarter code, and create products that truly serve users.</p>
<p>Whether you’re just starting or already experienced, investing time in UI/UX knowledge will set you apart and open new opportunities. Explore design resources, collaborate closely with designers, and experiment with small design tasks in your projects.</p>
<p>At the end of the day, the best front-end developers don’t just write code, they create experiences users love.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use CSS to Improve Web Accessibility ]]>
                </title>
                <description>
                    <![CDATA[ Did you know that CSS can play a significant role in web accessibility? While CSS primarily handles the visual presentation of a webpage, when you use it properly it can enhance the user’s experience and improve accessibility. In this article, I'll s... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-css-to-improve-web-accessibility/</link>
                <guid isPermaLink="false">66eb0a282e5bd4267b92ca10</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ a11y ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webdev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Elizabeth Lola ]]>
                </dc:creator>
                <pubDate>Wed, 18 Sep 2024 17:13:12 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726577970240/02631676-6492-4b83-a057-b9c2048709ee.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Did you know that CSS can play a significant role in web accessibility? While CSS primarily handles the visual presentation of a webpage, when you use it properly it can enhance the user’s experience and improve accessibility.</p>
<p>In this article, I'll share some ways CSS can support accessibility so you can start using these techniques in your own projects.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>To follow along with this tutorial, you should have a basic understanding of HTML, CSS, and a little bit of Javascript.</p>
<h2 id="heading-update-focus-styles">Update Focus Styles</h2>
<p>The browser provides default focus styles for interactive elements like buttons or input fields. But sometimes these default focus styles might not be ideal for your design system – especially if the colors used in your design are too close to the default colors. This might make it difficult to notice.</p>
<p>Also, different browsers have different default focus styles and you might want to standardize the focus styles to ensure uniformity.</p>
<p>You can change the default focus style of an element in CSS using the <code>:focus</code> pseudo-class. For example, the default focus style for an input element is a blue outline in Chrome and a blue outline with outline offset in Firefox, to update the default focus styles of an input element you can do this:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">input</span><span class="hljs-selector-pseudo">:focus</span> {
  <span class="hljs-attribute">outline</span>: <span class="hljs-number">2px</span> solid <span class="hljs-number">#007BFF</span>;
  <span class="hljs-attribute">outline-offset</span>: <span class="hljs-number">2px</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">1rem</span>;
}
</code></pre>
<h2 id="heading-avoid-content-shifts">Avoid Content Shifts</h2>
<p>Content shifts can happen when you’re lazy loading images, where images load progressively as the user scrolls down the page. Sometimes the image pushes the content around it downwards, shifting the text you're reading out of place.</p>
<p>Content shifts can also happen during dynamic content fetching, especially when new content like text, images, or ads is added to the page without reserving space for it in advance.</p>
<p>Content shifts can be frustrating, especially for users:</p>
<ul>
<li><p>With cognitive disabilities who may lose track of where they are in the content.</p>
</li>
<li><p>Using screen magnifiers, where the shift can cause them to lose their zoomed-in focus.</p>
</li>
<li><p>Navigating with a keyboard, as it can mess up the natural tab order and make navigation confusing.</p>
</li>
</ul>
<p>You can pre-allocate space for content to prevent shifts by using the <code>min-height</code> or <code>aspect-ratio</code> properties. Here's how you can allocate space for an image to prevent content shift before the image has fully loaded.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">img</span> {
    <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
    <span class="hljs-attribute">height</span>: auto;
    <span class="hljs-attribute">aspect-ratio</span>: <span class="hljs-number">16</span>/<span class="hljs-number">9</span>;
    <span class="hljs-attribute">object-fit</span>: cover; <span class="hljs-comment">/* Ensures the image fits well within the allocated space */</span>
}
</code></pre>
<p>You can also use animations or transitions when dynamically loading content to add smooth transitions for new content. So, instead of a sudden shift, the content slides in gracefully, reducing the perception of disruption.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.new-content</span> {
    <span class="hljs-attribute">transition</span>: margin <span class="hljs-number">0.3s</span> ease-in-out, opacity <span class="hljs-number">0.3s</span> ease-in-out;
}
</code></pre>
<h2 id="heading-reduce-motion">Reduce Motion</h2>
<p>Rapid animations or really complex transitions can be disorienting for users with motion sensitivity, which could lead to discomfort like headaches, dizziness, or vertigo (for users with vestibular disorders).</p>
<p>You can use CSS’s <code>prefers-reduced-motion</code> media query to reduce or disable animations for users.</p>
<p>Personally, instead of disabling animations completely, I replace complex, distracting animations with more subtle ones to maintain functionality while respecting user preferences.</p>
<p>Here's how to use <code>prefers-reduced-motion</code> to create a simpler animation:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* Default animation */</span>
<span class="hljs-keyword">@keyframes</span> complexAnimation {
    0% { <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(<span class="hljs-number">0</span>); <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>; }
    50% { <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(<span class="hljs-number">100px</span>); <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0.5</span>; }
    100% { <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(<span class="hljs-number">0</span>); <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>; }
}

<span class="hljs-selector-class">.element</span> {
    <span class="hljs-attribute">animation</span>: complexAnimation <span class="hljs-number">2s</span> ease-in-out;
}

<span class="hljs-comment">/* Simpler animation for reduced motion preference */</span>
<span class="hljs-keyword">@media</span> (<span class="hljs-attribute">prefers-reduced-motion:</span> reduce) {
    <span class="hljs-keyword">@keyframes</span> simpleAnimation {
        0% { <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>; }
        100% { <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>; }
    }

    <span class="hljs-selector-class">.element</span> {
        <span class="hljs-attribute">animation</span>: simpleAnimation <span class="hljs-number">1s</span> ease-in-out;
    }
}
</code></pre>
<p>Here’s an example from the code above. If you have reduced motion enabled you’ll see a fading ball instead of a moving ball:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/leezee/embed/preview/PorrrQW?default-tab=result&amp;editable=true" 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><strong>Note</strong>: If you want to see the reduced motion in action, you can enable it in the <a target="_blank" href="https://developer.chrome.com/docs/devtools/rendering">rendering tab on Google Chrome</a>.</p>
<h2 id="heading-focus-within-for-nested-elements">Focus Within for Nested Elements</h2>
<p>You can highlight or style a parent element when any of its child elements receive focus to make it clear which group (like form inputs or dropdown menus) is currently being interacted with.</p>
<p>To do this, you can use CSS’s <code>:focus-within</code> pseudo-class which is used to style an element when any of its descendants receive focus either through keyboard navigation or user interaction.</p>
<p>For example, to highlight a fieldset when any item in the group is focused in a grouped control, you can do this:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
 <span class="hljs-selector-tag">fieldset</span> {
   <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;
   <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ccc</span>;
 }

 <span class="hljs-selector-tag">fieldset</span><span class="hljs-selector-pseudo">:focus-within</span> {
   <span class="hljs-attribute">border-color</span>: <span class="hljs-number">#007BFF</span>; <span class="hljs-comment">/* highlight the fieldset when a user focuses on any input */</span>
 }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">fieldset</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">legend</span>&gt;</span>Choose a color:<span class="hljs-tag">&lt;/<span class="hljs-name">legend</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"color"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"red"</span>&gt;</span> Red<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"color"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"green"</span>&gt;</span> Green<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"color"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"blue"</span>&gt;</span> Blue<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">fieldset</span>&gt;</span>
</code></pre>
<h2 id="heading-customize-contrast-options">Customize Contrast Options</h2>
<p>Sometimes you may be working on a design that uses lots of colors and might not maintain high contrast between text and background to fit an aesthetic. Or perhaps you're working on a design with lots of bright colors. In these cases, you should consider how your application renders for different users.</p>
<p>Some users with low vision or certain types of color blindness might need high contrast mode to differentiate text from the background more clearly. Other users sensitive to bright colors might prefer a softer, less jarring visual experience.</p>
<p>Some of these users might have their systems set to high or low contrast to help improve their experience. To customize their experience, you can use the CSS <code>prefers-contrast</code> media query.</p>
<p>The <code>prefers-contrast</code> media query allows you to tailor the contrast of your website or application based on the user's system settings.</p>
<p>Here's an example of using <code>prefers-contrast</code>:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* default styling preference */</span>
<span class="hljs-selector-tag">body</span> {
    <span class="hljs-attribute">background-color</span>: white;
    <span class="hljs-attribute">color</span>: black;
}

<span class="hljs-comment">/* high contrast preference */</span>
<span class="hljs-keyword">@media</span> (<span class="hljs-attribute">prefers-contrast:</span> more) {
    <span class="hljs-selector-tag">body</span> {
        <span class="hljs-attribute">background-color</span>: black;
        <span class="hljs-attribute">color</span>: white;
    }
    <span class="hljs-selector-tag">a</span> {
        <span class="hljs-attribute">color</span>: yellow;
    }
}
<span class="hljs-comment">/* low contrast preference */</span>

<span class="hljs-keyword">@media</span> (<span class="hljs-attribute">prefers-contrast:</span> less) {
    <span class="hljs-selector-tag">body</span> {
        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f0f0f0</span>;
        <span class="hljs-attribute">color</span>: <span class="hljs-number">#333</span>;
    }
    <span class="hljs-selector-tag">a</span> {
        <span class="hljs-attribute">color</span>: <span class="hljs-number">#555</span>;
    }
}
</code></pre>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/leezee/embed/preview/dyBBxgV?default-tab=result&amp;editable=true" 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>In the example above, the <code>prefers-contrast: more</code> option ensures that when a user prefers high contrast, the background is black and the text is white, with yellow links for better visibility.</p>
<p>The <code>prefers-contrast: less</code> adjusts the color scheme to a softer color for users who prefer less contrast. The default style is used if the user has no specific contrast preference or if their preference is not detected.</p>
<p><strong>Note</strong>: If your design uses minimal colors and maintains high contrast between text and background or you're working with a design where text is minimal and the focus is on visual content (like image galleries or video players), you might not need <code>prefers-contrast</code> as much. But it's still good practice to consider contrasts.</p>
<h2 id="heading-enable-dark-mode">Enable Dark Mode</h2>
<p>You can use CSS to accommodate users’ preferences for dark or light modes. You can achieve this through the CSS <code>prefers-color-scheme</code> media query. The browser can detect the user's color preference and apply the style if provided in CSS.</p>
<p>Here's an example of how you can add a dark mode style to your site using CSS variables:</p>
<pre><code class="lang-css"><span class="hljs-selector-pseudo">:root</span> {
  <span class="hljs-attribute">--background-color</span>: <span class="hljs-number">#ffffff</span>;
  <span class="hljs-attribute">--text-color</span>: <span class="hljs-number">#000000</span>;
}

<span class="hljs-keyword">@media</span> (<span class="hljs-attribute">prefers-color-scheme:</span> dark) {
  <span class="hljs-selector-pseudo">:root</span> {
    <span class="hljs-attribute">--background-color</span>: <span class="hljs-number">#000000</span>;
    <span class="hljs-attribute">--text-color</span>: <span class="hljs-number">#ffffff</span>;
  }
}

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">var</span>(--background-color);
  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--text-color);
}
</code></pre>
<p>In the example above, the variables get updated if the browser detects a dark color scheme preference.</p>
<p>If you want to allow users to toggle between modes manually, you can use JavaScript for this:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
 <span class="hljs-comment">/* Default light mode styles */</span>
  <span class="hljs-selector-tag">body</span> {
   <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#ffffff</span>;
   <span class="hljs-attribute">color</span>: <span class="hljs-number">#000000</span>;
  }
 <span class="hljs-comment">/* Dark mode styles */</span>
  <span class="hljs-selector-tag">body</span><span class="hljs-selector-class">.dark-mode</span> {
   <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#000000</span>;
   <span class="hljs-attribute">color</span>: <span class="hljs-number">#ffffff</span>;
  }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"toggle-theme"</span>&gt;</span>Toggle Theme<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">const</span> toggleButton = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'toggle-theme'</span>);
  toggleButton.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
   <span class="hljs-built_in">document</span>.body.classList.toggle(<span class="hljs-string">'dark-mode'</span>);
  });
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-use-rem-units-for-responsive-typography">Use <code>rem</code> Units for Responsive Typography</h2>
<p>Using <code>rem</code> units for responsive typography can help enhance accessibility to adapt more dynamically to a user's preference. Since <code>rem</code> is relative to the root font size (typically set by the browser or user), it scales with changes in the base font size. This helps ensure that text remains readable without breaking layouts.</p>
<p>Users can set a preferred font size in their browser or operating system for better readability. When you use <code>rem</code>, the website content scales according to this setting which ensures that the text is not too small or too large for the users (which can happen when using fixed units like <code>px</code>).</p>
<p>When users zoom in using browser settings or increase their preferred text size, the <code>rem</code>-based text will scale appropriately.</p>
<p>The default root font size (usually 16px) is typically inherited from the browser, but you can set it explicitly if needed:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">html</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">100%</span>; <span class="hljs-comment">/* Default 16px */</span>
}
</code></pre>
<p>After setting the root font size, you can use <code>rem</code> unit for the rest of your content. For example:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2.5rem</span>; <span class="hljs-comment">/* Equivalent to 40px if root is 16px */</span>
}

<span class="hljs-selector-tag">p</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1rem</span>; <span class="hljs-comment">/* Equivalent to 16px */</span>
}
</code></pre>
<h2 id="heading-use-animations-to-enhance-ux">Use Animations to Enhance UX</h2>
<p>CSS animations can enhance accessibility when used thoughtfully. They can help create an engaging and understandable experience for users.</p>
<p>Here are some ways that animations can help improve accessibility:</p>
<ul>
<li><p>You can use animations to indicate loading state to visually communicate to users that the system is working on a task.</p>
</li>
<li><p>Using animated text effects, like fades or scaling on headlines or important sections, can help guide users' eyes to important content. This can be useful for people with cognitive disabilities who benefit from clear visual hierarchies.</p>
</li>
<li><p>Subtle transitions for state change instead of having abrupt changes (like a modal popping up instantly) can create smoother transitions between different interface states.</p>
</li>
<li><p>Using animated highlights or shaking effects on form fields can provide visual feedback to users about input errors. You should pair these animations with labels or ARIA attributes to make it clear what the user needs to correct.</p>
</li>
<li><p>Animations can help users track focus, especially keyboard users or those with visual impairments. CSS transitions that highlight focused elements (for example by enlarging buttons or changing the border) assist users in understanding where they are within the page.</p>
</li>
</ul>
<h3 id="heading-best-practices">Best Practices:</h3>
<ul>
<li><p>Ensure animations are used purposefully, not just for aesthetic reasons.</p>
</li>
<li><p>Avoid overly long or continuous animations that can distract or annoy users.</p>
</li>
<li><p>Combine animations with other accessible features, such as screen reader announcements, to ensure all users understand content changes.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>When considering accessibility, well-structured HTML forms the foundation of an accessible page – but CSS also plays a vital role in enhancing that structure.</p>
<p>CSS alone cannot fix poorly structured HTML. But when it’s applied thoughtfully to a solid foundation, it ensures a more inclusive and engaging experience by improving visual hierarchy, readability, and interaction for users of all abilities.</p>
<p>Combining accessible HTML with CSS not only improves the user interface but also provides support for assistive technologies.</p>
<p>Thank you so much for reading this article. If you found it helpful, consider sharing. Happy coding!</p>
<p>You can connect with me on <a target="_blank" href="https://www.linkedin.com/in/elizabeth-meshioye/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ From Fashion to Software Engineer with Alison Yoon [Podcast #130] ]]>
                </title>
                <description>
                    <![CDATA[ On this week's episode of the podcast, freeCodeCamp founder Quincy Larson interviews Alison Yoon. She's a Software Engineer who started off in fashion design and taught herself to code using freeCodeCamp. We talk about: What it's like to work in fas... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/from-fashion-to-software-engineer-with-alison-yoon-podcast-130/</link>
                <guid isPermaLink="false">667edce8aa563b3222630d0d</guid>
                
                    <category>
                        <![CDATA[ podcast ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learn to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Fri, 28 Jun 2024 15:55:20 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1719586519264/2a48adf1-4bca-4cf7-8cb6-c40471453d6e.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>On this week's episode of the podcast, freeCodeCamp founder Quincy Larson interviews Alison Yoon. She's a Software Engineer who started off in fashion design and taught herself to code using freeCodeCamp.</p>
<p>We talk about:</p>
<ul>
<li><p>What it's like to work in fashion. "You're surrounded by exhausted, unhappy people."</p>
</li>
<li><p>How she used freeCodeCamp and the 100DaysOfCode challenge to learn to code and start her software development career</p>
</li>
<li><p>How she learned English and how to work on engineering teams in the UK.</p>
</li>
<li><p>How she's leading the Korean translation effort for the freeCodeCamp community, with 10,000s of people now reading Korean articles each month</p>
</li>
</ul>
<p>Can you guess what song I'm playing on my bass during the intro? It's from a 1985 song.</p>
<p>Also, I want to thank the 9,779 kind people who support our charity each month, and who make this podcast possible. You can join them and support our mission at: <a target="_blank" href="https://www.freecodecamp.org/donate">https://www.freecodecamp.org/donate</a></p>
<p>You can watch the interview on YouTube:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/DJyZtXwUjIE" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Or you can listen to the podcast in Apple Podcasts, Spotify, or your favorite podcast app. You can also listen to the podcast below, right in your browser:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="152" src="https://open.spotify.com/embed/episode/1PQnJ3m8lSaB7laHiJEcEs" style="" title="Spotify embed" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Links we talk about during our conversation:</p>
<ul>
<li><p>freeCodeCamp's Korean edition, including Quincy's "Learn to code and get a developer job" book translated into Korean: <a target="_blank" href="https://www.freecodecamp.org/korean/news/learn-to-code-book/">https://www.freecodecamp.org/korean/news/learn-to-code-book/</a></p>
</li>
<li><p>Alison on Twitter: <a target="_blank" href="https://twitter.com/aliyooncreative">https://twitter.com/aliyooncreative</a></p>
</li>
<li><p>Devil Wears Prada trailer: <a target="_blank" href="https://www.youtube.com/watch?v=6ZOZwUQKu3E">https://www.youtube.com/watch?v=6ZOZwUQKu3E</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Quincy Interviews Colby Fayock: Dev, Designer, Male Model, Prolific fCC Contributor [Podcast #128] ]]>
                </title>
                <description>
                    <![CDATA[ On this week's episode of the podcast, I interview Colby Fayock. He's a Software Engineer and prolific teacher who has created 68 tutorials for freeCodeCamp, and more than 100 videos on his YouTube – all freely available. We talk about: Colby's earl... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/quincy-interviews-colby-fayock-dev-designer-male-model-prolific-fcc-contributor-podcast-128/</link>
                <guid isPermaLink="false">666b7cfc413982194a86bfa5</guid>
                
                    <category>
                        <![CDATA[ podcast ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Thu, 13 Jun 2024 23:13:00 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1718320315765/f045aec5-575f-40c5-967e-36d16de7a01c.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>On this week's episode of the podcast, I interview Colby Fayock. He's a Software Engineer and prolific teacher who has created 68 tutorials for freeCodeCamp, and more than 100 videos on his YouTube – all freely available.</p>
<p>We talk about:</p>
<ul>
<li><p>Colby's early days doing design work for local bands</p>
</li>
<li><p>How Colby went to art school, then pivoted that into a software development</p>
</li>
<li><p>His early career at ThinkGeek where he not only did web dev but also worked as a male model for their products.</p>
</li>
<li><p>Colby's day-to-day work as a developer experience engineer, building demo applications and SDKs</p>
</li>
<li><p>How Colby uses AI tools in his day-to-day work, and what he thinks its current limits are.</p>
</li>
</ul>
<p>Can you guess what song I'm playing on my bass during the intro? It's from a 1995 punk song.</p>
<p>Also, I want to thank the 9,771 kind people who support our charity each month, and who make this podcast possible. You can join them and support our mission at: <a target="_blank" href="https://www.freecodecamp.org/donate">https://www.freecodecamp.org/donate</a></p>
<p>You can watch the interview on YouTube:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/DL5HvYyJjM0" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Or you can listen to the podcast in Apple Podcasts, Spotify, or your favorite podcast app. You can also listen to the podcast below, right in your browser:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="152" src="https://open.spotify.com/embed/episode/48cCVVKpw1TDb2VNOxIkmC" style="" title="Spotify embed" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Links we talk about during our conversation:</p>
<ul>
<li>Colby's freeCodeCamp course on building a clone of Google Photos using AI tools and Next.js: <a target="_blank" href="https://www.freecodecamp.org/news/create-a-google-photos-clone-with-nextjs-and-cloudinary/">https://www.freecodecamp.org/news/create-a-google-photos-clone-with-nextjs-and-cloudinary/</a></li>
</ul>
<ul>
<li><p>Colby's Trailer and web design work: <a target="_blank" href="https://photowall-colbyfayock.vercel.app/wall/design">https://photowall-colbyfayock.vercel.app/wall/design</a></p>
</li>
<li><p>Colby's ThinkGeek Modeling. He's legit a male model: <a target="_blank" href="https://photowall-colbyfayock.vercel.app/wall/thinkgeek">https://photowall-colbyfayock.vercel.app/wall/thinkgeek</a></p>
</li>
<li><p>Colby's music from his band years: <a target="_blank" href="https://soundcloud.com/colby-fayock/sets/day-late-hero">https://soundcloud.com/colby-fayock/sets/day-late-hero</a></p>
</li>
<li><p>The XKCD comic I mention about how the scope of developer work can be non-intuitive: <a target="_blank" href="https://xkcd.com/1425/">https://xkcd.com/1425/</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Viewing Patterns in Your Website Designs ]]>
                </title>
                <description>
                    <![CDATA[ While going through a website or an application, people tend to take in the information displayed differently. You may notice that sometimes a person may miss information that others wouldn't miss. This may have happened to you before, as well. This ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-viewing-patterns-in-your-website-design/</link>
                <guid isPermaLink="false">66d03a30ab216b4115759499</guid>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Faith Olohijere ]]>
                </dc:creator>
                <pubDate>Wed, 12 Jun 2024 14:33:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/06/pexels-ramilugot-5011944.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>While going through a website or an application, people tend to take in the information displayed differently. You may notice that sometimes a person may miss information that others wouldn't miss. This may have happened to you before, as well.</p>
<p>This is because everyone has a particular way they process information. In design, this is called viewing (or reading) patterns. As a designer, it's important to understand how your users (including potential ones) consume information, and how best to place the most crucial information so nobody misses it.</p>
<p>In this article, we'll talk about different viewing patterns, how to choose the best ones for your project, and we'll also see real-life examples of these patterns.</p>
<h3 id="heading-heres-what-well-cover">Here's what we'll cover:</h3>
<ol>
<li>What you need to know before reading</li>
<li>The origin of viewing patterns</li>
<li>Common viewing patterns</li>
<li>Why are viewing patterns important?</li>
<li>How should I choose a viewing pattern for my design project?</li>
<li>Conclusion</li>
</ol>
<h2 id="heading-prerequisites">Prerequisites:</h2>
<p>Before we go into the article proper, please note that it'll be helpful if you have basic knowledge of core design principles and the importance of these principles in guiding users' attention and organizing information effectively. </p>
<p>But this is not necessary, as I wrote this article for everyone, including absolute beginners.</p>
<h2 id="heading-the-origin-of-viewing-patterns">The Origin of Viewing Patterns</h2>
<p>The concept of viewing patterns can be traced to the field of psychology, specifically the study of eye movements and visual perception. </p>
<p>While people have been reading and consuming visual information for a long time, proper observation and analysis of reading behaviors emerged with the development of eye-tracking technology and scientific research methodologies in the late 19th and early 20th centuries.</p>
<p>A lot of pioneers and researchers such as Louis Emile Javal, Edmund Huey, Alfred L. Yarbus, and Charles H. Judd conducted experiments to observe eye movemts and behaviours in the late 19th century and early to mid-20th century.</p>
<p>The formalization of viewing/reading patterns as design principles in the context of graphic design and information architecture began to gain traction in the latter half of the 20th century. Designers and usability experts started applying insights from eye-tracking studies to optimize layouts for print media, signage, and digital interfaces.</p>
<p>Over time, the study of viewing patterns expanded beyond text-based reading to include diverse media formats, such as web pages, multimedia presentations, and interactive interfaces. </p>
<p>Today, viewing patterns continue to evolve with advancements in technology and changes in user behaviors, guiding the way designers approach layout, navigation, and content presentation.</p>
<h2 id="heading-common-viewing-patterns">Common Viewing Patterns</h2>
<p>Now that we know how viewing patterns came about, let's talk about some common viewing patterns in existence.</p>
<h3 id="heading-the-f-pattern">The F-pattern</h3>
<p>This is a common viewing pattern observed in online content consumption. According to this pattern, users scan the page in a horizontal movement across the top, then move down the page, scanning shorter horizontal sections. They continue to read less of the content, until they finally start reading vertically, forming the F-shape.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-56.png" alt="Image" width="600" height="400" loading="lazy">
<em>Diagram illustrating how the F-pattern works on a wireframe. Image Credit: <a target="_blank" href="https://www.nngroup.com/articles/f-shaped-pattern-reading-web-content/">Nielsen Norman Group</a></em></p>
<p>To capitalize on the F-pattern, you can place important information such as headlines, key points, and CTAs along the top and the left-hand side of the page to ensure maximum visibility. </p>
<p>Some examples of real-life platforms that utilize the F-pattern include:</p>
<ul>
<li><a target="_blank" href="https://shopify.com/">Shopify</a></li>
<li><a target="_blank" href="https://linkedin.com/">LinkedIn</a></li>
<li><a target="_blank" href="https://www.nytimes.com/">The New York Times</a></li>
</ul>
<h3 id="heading-the-z-pattern">The Z-Pattern</h3>
<p>The Z-pattern is another common viewing pattern. This pattern can be noticed in designs where the user is expected to move their eyes in a zig-zag pattern across the page. </p>
<p>This pattern typically starts with a horizontal movement across the top of the page (forming the first stroke of the "Z"), followed by a diagonal movement from the top-right to the bottom-left (forming the second stroke), and finally, another horizontal movement across the bottom of the page (completing the "Z"). </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Z-pattern.png" alt="Image" width="600" height="400" loading="lazy">
<em>Diagram illustrating the Z-pattern. Image Credit: <a target="_blank" href="https://uxplanet.org/z-shaped-pattern-for-reading-web-content-ce1135f92f1c">UX Planet</a></em></p>
<p>To capitalize on this pattern, you can align information on the predicted path of the Z-pattern to guide users' attention more effectively, especially in designs like landing pages and presentations.</p>
<p>Some examples of real-life platforms that utilize the Z-pattern include:</p>
<ul>
<li><a target="_blank" href="https://artykul.org/https://artykul.org/">Artykul</a></li>
<li><a target="_blank" href="https://www.mohash.co/">Mohash</a></li>
<li><a target="_blank" href="https://desclimbing.com/">Des Climbing</a></li>
</ul>
<h3 id="heading-the-gutenberg-diagram">The Gutenberg Diagram</h3>
<p>The Gutenberg diagram outlines a viewing pattern based on the natural eye movement of Western readers, and is influenced by cultural and linguistic factors. </p>
<p>The Gutenberg Diagram divides the page into four quadrants: the primary optical area (top-left), the strong fallow area (top-right), the weak fallow area (bottom-left), and the terminal area (bottom-right).</p>
<blockquote>
<p>The pattern suggests that the eye will sweep across and down the page in a series of horizontal movements called axes of orientation. Each sweep starts a little further from the left edge and moves a little closer to the right edge. The overall movement is for the eye to travel from the primary area to the terminal area... – Stephen Bradley (<a target="_blank" href="https://vanseodesign.com/web-design/3-design-layouts/">Vanseo Design</a>)</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-1--3-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image illustrating Gutenberg diagram divided into 4 quadrants. Image Credit: <a target="_blank" href="https://www.techwala.in/gutenberg-diagram-why-you-should-know-it-and-use-it/">Techwala</a></em></p>
<p>You can strategically place content based on the Gutenberg diagram to optimize visual hierarchy and readability, ensuring that important information receives the most attention.</p>
<p>Some examples of real-life platforms that utilize the Gutenberg diagram include:</p>
<ul>
<li><a target="_blank" href="http://www.wikipedia.org/">Wikipedia</a></li>
<li><a target="_blank" href="http://www.bbc.com/news">BBC News</a></li>
</ul>
<h3 id="heading-layer-cake-pattern">Layer-Cake Pattern</h3>
<p>The layer-cake pattern involves stacking multiple layers of content vertically, with each layer containing distinct information or visual elements.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-3--1-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image illustrating the layer-cake pattern on a layout. Image Credit: <a target="_blank" href="https://chipcullen.com/layer-cake-design-pattern/">Chip Cullen</a></em></p>
<p>Users typically engage with this pattern by scanning the top layer first, then sequentially exploring deeper layers based on their interest or curiosity. You can use this pattern to present complex information in a more structured format, allowing users to navigate through layers of content at their own pace.</p>
<p>Some examples of real-life platforms that utilize the Layer-Cake pattern include:</p>
<ul>
<li><a target="_blank" href="http://www.medium.com/">Medium</a></li>
<li><a target="_blank" href="http://www.squarespace.com/">Squarespace</a></li>
</ul>
<h2 id="heading-why-are-viewing-patterns-important">Why are Viewing Patterns Important?</h2>
<p>Viewing patterns help you guide how users view and consume information on your designs. They help you arrange content in a way that naturally aligns with your users' reading habits. By placing information where users are most likely to look first, you're ensuring that key messages are effectively communicated. </p>
<p>Also, understanding viewing patterns help you cater to the needs of a diverse group of users. Different people process information in different ways and understanding these habits ensure that you design with accessibility in mind.</p>
<p>What's more, designs that align with existing viewing patterns provide a more intuitive and less stressful user experience. </p>
<h2 id="heading-how-should-i-choose-a-viewing-pattern-for-my-design-project">How Should I Choose a Viewing Pattern for my Design Project?</h2>
<p>Choosing a viewing pattern for your design depends on a number of factors including, the context of your project, users' preferences, goals of the project, and so on. </p>
<p>Here's a step-by-step guide to help you select the best reading pattern for your project:</p>
<ol>
<li>Know your Users: You have to first understand the demographics of your target or potential users. What do they prefer? What are their goals? In what situations would they use your project? Gather insights into how they interact with content and their technical proficiency.</li>
<li>Define your Project Goals: Make sure to clarify the objectives and desired outcomes of the project you're working on. Are you trying to inform or facilitate a specific action? Should your design be very serious or a little playful? You need to identify the key messages you want to pass across to your users, and prioritize them based on importance. </li>
<li>Evaluate Context and Platform: Take into account how your users would view your product. Will they view your content on a website, application or a print medium? Consider the device types and screen sizes that your users are likely to use.</li>
<li>Select Viewing Pattern: Considering the available data and the insights you've gathered, you can go ahead to choose a viewing pattern that best aligns with your project objectives. </li>
</ol>
<p>Now that you've selected a viewing pattern for your design, make sure to constantly monitor it's effectiveness through testing and feedback.</p>
<p>Note: You can interchange these steps or even skip some. Just make sure to do whatever works best for your users.</p>
<h3 id="heading-lets-do-a-little-practical-exercise">Let's do a little practical exercise:</h3>
<p>Say you're working on a hero section for a new e-commerce website selling outdoor gear. Some things you need to consider for this project include:</p>
<ul>
<li>The primary goal: to showcase the latest product offerings on the hero section and entice visitors to visit the website further. You'll want to highlight key features, products, and calls-to-action (CTAs) to encourage conversion such as making a purchase or signing up for a newsletter.</li>
<li>Your target users: likely outdoor enthusiasts, including hikers, campers, and adventure seekers. They'll likely be people with limited time to spend on each webpage.</li>
<li>Context and platform: Users will likely access the page on several devices, including desktop computers, laptops, tablets, and smartphones. You'll want to consider how the design will adapt responsively across different screen sizes and orientations, priortizing mobile optimization for on-the-go users.</li>
</ul>
<p>Due to the time constraints of your users, and the need to capture attention quickly, the F-pattern may be a suitable choice. Place high-priority content, such as featured products, top deals, and prominent CTAs, along the top and left-hand side of the page, where users are most likely to look first. </p>
<p>You can use visual cues such as arrows, bold typography, and contrasting colors to draw attention to key elements and guide users' eye movements down the page.</p>
<p>Here's what I came up with from the practical design:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Frame-19-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Hero section I designed using the F-pattern.</em></p>
<p>In the design above, in sequential order, there's:</p>
<ul>
<li>a top navigation containing the logo, links to other sub-pages, and the log-in and sign up CTAs(call-to-actions).</li>
<li>a main heading, description, and call-to-action (Shop Now) on the left-hand side of the page.</li>
<li>a section showing latest arrivals on the website.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Frame-20--3--1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image showing how the F-pattern is depicted on the design.</em></p>
<p>I would love to see the results of this practical exercise on your end.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Viewing patterns are very important as I mentioned earlier. They are invaluable for designers across different disciplines, and are easy to understand and incorporate into your designs. </p>
<p>You just need to be sure of what works best for your users, and design with that in mind. Also make sure to experiment with different viewing patterns so you can discover your own unique style. Have fun experimenting!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Become a Pro Designer [Interview with Gary Simon Podcast #123] ]]>
                </title>
                <description>
                    <![CDATA[ On this week's episode of the podcast, I interview Gary Simon, a developer and designer who started DesignCourse and has published several courses on freeCodeCamp.org over the years. We talk about: Growing up in rural Ohio, marrying young, and stayi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-become-a-pro-designer-in-2024-interview-with-gary-simon-podcast-123/</link>
                <guid isPermaLink="false">663e61f93f6496fbe66c72b5</guid>
                
                    <category>
                        <![CDATA[ podcast ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Entrepreneurship ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Fri, 10 May 2024 18:05:45 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1715398245475/df3e1138-477a-4718-9f59-5608e611f4a3.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>On this week's episode of the podcast, I interview Gary Simon, a developer and designer who started DesignCourse and has published several courses on <a target="_blank" href="http://freeCodeCamp.org">freeCodeCamp.org</a> over the years.</p>
<p>We talk about:</p>
<ul>
<li><p>Growing up in rural Ohio, marrying young, and staying out there despite his success as a developer and entrepreneur</p>
</li>
<li><p>Early client work, and how he designed thousands of logos for clients before becoming an all-out web developer</p>
</li>
<li><p>Using his skills to help his wife start her own lactation consultant business online</p>
</li>
<li><p>Gary's guitar shredding chops</p>
</li>
</ul>
<p>I recorded this podcast live and I haven't edited it at all. I want to capture the feel of a real live conversation, with all the human quirks that entails.</p>
<p>Can you guess what song I'm playing on my bass during the intro? It's from a 1995s Nintendo game.</p>
<p>Be sure to follow The freeCodeCamp podcast in your favorite podcast app. And share this podcast with a friend. Let's inspire more folks to learn to code and build careers for themselves in tech.</p>
<p>You can watch the interview on YouTube:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/h4puc1P2VMA" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Or you can listen to the podcast in Apple Podcasts, Spotify, or your favorite podcast app. You can also listen to the podcast below, right in your browser:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="152" src="https://open.spotify.com/embed/episode/7hx0sDb5HPxtwGEMRXCGtd" style="" title="Spotify embed" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Also, I want to thank the 9,331 kind people who support our charity each month, and who make this podcast possible. You can join them and support our mission at: <a target="_blank" href="https://www.freecodecamp.org/donate">https://www.freecodecamp.org/donate</a></p>
<p>Links we talk about during the interview:</p>
<ul>
<li><p>Gary's Learn UI Fundamentals course on freeCodeCamp: <a target="_blank" href="https://www.freecodecamp.org/news/learn-ui-design-fundamentals-with-this-free-one-hour-course/">https://www.freecodecamp.org/news/learn-ui-design-fundamentals-with-this-free-one-hour-course/</a></p>
</li>
<li><p>Gary's freeCodeCamp live stream series: <a target="_blank" href="https://www.freecodecamp.org/news/design-course/">https://www.freecodecamp.org/news/design-course/</a></p>
</li>
<li><p>Gary's tool for memorizing the Guitar fretboard and it's 49 notes: <a target="_blank" href="https://fretastic.com/">https://fretastic.com/</a></p>
</li>
<li><p>Gary's Retrowave Guitar music video: <a target="_blank" href="https://www.youtube.com/watch?v=yDc2OvReYh0">https://www.youtube.com/watch?v=yDc2OvReYh0</a></p>
</li>
</ul>
<p>On this week's episode of the podcast, I interview Gary Simon, a developer and designer who started DesignCourse and has published several courses on <a target="_blank" href="http://freeCodeCamp.org">freeCodeCamp.org</a> over the years.</p>
<p>We talk about:</p>
<ul>
<li><p>Growing up in rural Ohio, marrying young, and staying out there despite his success as a developer and entrepreneur</p>
</li>
<li><p>Early client work, and how he designed thousands of logos for clients before becoming an all-out web developer</p>
</li>
<li><p>Using his skills to help his wife start her own lactation consultant business online</p>
</li>
<li><p>Gary's guitar shredding chops</p>
</li>
</ul>
<p>I recorded this podcast live and I haven't edited it at all. I want to capture the feel of a real live conversation, with all the human quirks that entails.</p>
<p>Can you guess what song I'm playing on my bass during the intro? It's from a 1995s Nintendo game.</p>
<p>Be sure to follow The freeCodeCamp podcast in your favorite podcast app. And share this podcast with a friend. Let's inspire more folks to learn to code and build careers for themselves in tech.</p>
<p>You can watch the interview on YouTube:</p>
<p>Or you can listen to the podcast in Apple Podcasts, Spotify, or your favorite podcast app. You can also listen to the podcast below, right in your browser:</p>
<p>Also, I want to thank the 9,331 kind people who support our charity each month, and who make this podcast possible. You can join them and support our mission at: <a target="_blank" href="https://www.freecodecamp.org/donate">https://www.freecodecamp.org/donate</a></p>
<p>Links we talk about during the interview:</p>
<ul>
<li><p>Gary's Learn UI Fundamentals course on freeCodeCamp: <a target="_blank" href="https://www.freecodecamp.org/news/learn-ui-design-fundamentals-with-this-free-one-hour-course/">https://www.freecodecamp.org/news/learn-ui-design-fundamentals-with-this-free-one-hour-course/</a></p>
</li>
<li><p>Gary's freeCodeCamp live stream series: <a target="_blank" href="https://www.freecodecamp.org/news/design-course/">https://www.freecodecamp.org/news/design-course/</a></p>
</li>
<li><p>Gary's tool for memorizing the Guitar fretboard and it's 49 notes: <a target="_blank" href="https://fretastic.com/">https://fretastic.com/</a></p>
</li>
<li><p>Gary's Retrowave Guitar music video: <a target="_blank" href="https://www.youtube.com/watch?v=yDc2OvReYh0">https://www.youtube.com/watch?v=yDc2OvReYh0</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Bento Grids Design in Your Web Projects ]]>
                </title>
                <description>
                    <![CDATA[ I believe we may have all noticed the trend of meticulously organized web layouts reminiscent of Japanese bento boxes. These 'Bento Grids' have swiftly gained traction, offering a visually appealing and structurally cohesive way to present content on... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/bento-grids-in-web-design/</link>
                <guid isPermaLink="false">66bb88f4add24ba4273250de</guid>
                
                    <category>
                        <![CDATA[ CSS Grid ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ projects ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Jaja ]]>
                </dc:creator>
                <pubDate>Thu, 04 Apr 2024 10:06:39 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/Article-cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I believe we may have all noticed the trend of meticulously organized web layouts reminiscent of Japanese bento boxes. These 'Bento Grids' have swiftly gained traction, offering a visually appealing and structurally cohesive way to present content online.</p>
<p>In this article, we'll delve into the origins, rise, and practical implementation of the bento grid trend, exploring how it intersects aesthetics with functionality in modern web design.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li>Fundamentals of HTML and CSS (CSS Grid)</li>
<li>Basics of Web Design</li>
</ul>
<h2 id="heading-the-philosophy-behind-bento-grids">The Philosophy Behind Bento Grids</h2>
<p>The concept of bento grids traces back to the Japanese tradition of serving a variety of dishes in a single, segmented container known as a bento box. This method of presentation not only ensures a balanced meal but also pleases the eye with its organization and simplicity.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Bento-Japenese.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Bento Japanese Box</em></p>
<p>Translated into web design, bento grids offer a similar experience: diverse content segmented into distinct areas, making it both accessible and aesthetically balanced.</p>
<p>The bento grid philosophy hinges on compartmentalization and organization. It creates a predictable rhythm that users can follow, reducing cognitive load and enhancing the overall user experience. The design's symmetry and order offers a sense of calm and control, appealing to users' desire for simplicity and structure amidst the chaos of the internet.</p>
<h2 id="heading-the-rise-of-bento-grids">The Rise of Bento Grids</h2>
<p>While the use of grids in design is not new, the specific trend of bento grids began to gain traction as designers sought to create more organized and mobile-responsive layouts. </p>
<p>Powerhouses like Apple use this design pattern in promotional videos for their products as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Apple-mac-promotional-infographic.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Apple mac promotional infographic</em></p>
<p>The trend also saw a surge in popularity with the advent of CSS Grid Layout and the growing focus on minimalist design that doesn't sacrifice functionality for form.</p>
<p>Platforms that emphasize content, such as online magazines, educational sites, and portfolios, were among the early adopters of bento grids. Their adoption highlighted the grid's ability to present diverse content types in a harmonious layout, thereby improving navigation and readability.</p>
<h2 id="heading-examining-the-trend">Examining the Trend</h2>
<p>Clean lines, geometric shapes, and a clear space division often characterize modern bento grids. They usually consist of:</p>
<ul>
<li>The title of a feature</li>
<li>A short description of the feature</li>
<li>Some infographic or interactive content.</li>
</ul>
<p>This trend has been propelled by its positive impact on user experience. A well-implemented bento grid guides users through the website with ease, allowing quick access to information without overwhelming them with choices.</p>
<h2 id="heading-pros-of-using-bento-grids">Pros of Using Bento Grids</h2>
<ol>
<li><strong>Enhanced Organization and Cohesion</strong>: Bento grids bring a high level of organization to web design, allowing for a cohesive presentation of varied content. This segmentation makes it easier for users to digest information in a structured manner.</li>
<li><strong>Aesthetic Appeal</strong>: The symmetry and clean lines inherent in bento grids are visually appealing, providing a neat and professional look that can enhance the visual identity of a website.</li>
<li><strong>Reduced Scroll Fatigue</strong>: By efficiently utilizing space within a single viewport, bento grids can display a significant amount of content, which can reduce the need for excessive scrolling.</li>
<li><strong>Metaphorical Clarity</strong>: The bento box metaphor effectively communicates the concept of a complete and balanced experience, which can be particularly useful for showcasing product features or a portfolio of work.</li>
<li><strong>Improved Navigation</strong>: The predictability and order of bento grids aid in straightforward navigation, as users can easily move from one compartmentalized section to another.</li>
<li><strong>Compatibility with Responsive Design</strong>: Bento grids seamlessly integrate with responsive design principles, facilitating effortless adjustment of a website's layout to accommodate diverse screen sizes and devices.</li>
<li><strong>Focus on Content</strong>: The grid layout emphasizes content without unnecessary distractions, which can be crucial for sites where content is important, such as online galleries or information-driven platforms. </li>
<li><strong>Facilitates Comprehensive Product Capture</strong>: In the context of showcasing products, bento grids offer users the convenience of capturing all essential information at once. With content neatly organized within distinct compartments, users can easily screenshot or save a single view of the grid, ensuring they capture all relevant details without the need for multiple interactions or navigating through various pages.</li>
</ol>
<h2 id="heading-cons-of-bento-grids">Cons of Bento Grids</h2>
<ol>
<li><strong>Potential Information Overload</strong>: While bento grids can reduce cognitive load through organization, there's a risk of cramming too much information into a single screen, potentially overwhelming users.</li>
<li><strong>Limited Visual Hierarchy</strong>: The uniform structure of bento grids can sometimes lead to a lack of visual hierarchy, making it harder for users to determine the importance of certain content over others.</li>
<li><strong>Considerations Regarding Hick's Law</strong>: A densely packed grid presents users with a multitude of options, potentially prolonging their decision-making process. This abundance of choices can result in the paradox of choice, where <a target="_blank" href="https://lawsofux.com/hicks-law/">users experience indecision or slower navigation due to the overwhelming array of options available</a>.</li>
<li><strong>Design Rigidity</strong>: The structured nature of bento grids can sometimes restrict creative design elements and lead to a monotonous user experience if not implemented with variation and dynamic content.</li>
<li><strong>SEO Challenges</strong>: Search engines may have difficulty parsing the relevance of content when it's distributed across numerous grid compartments, potentially impacting SEO if not structured properly.</li>
<li><strong>Accessibility Concerns</strong>: The compartmentalized nature of bento grids might present accessibility challenges, particularly for users who rely on screen readers or keyboard navigation, if not designed with accessibility standards in mind.</li>
</ol>
<h2 id="heading-bento-grids-in-practice">Bento Grids in Practice</h2>
<p>Creating bento grids typically involves CSS grid layout and flexbox, which offer robust solutions for creating complex layouts with ease. Bento grids are favored for their flexibility and responsiveness, allowing content to reflow seamlessly across different screen sizes.</p>
<p>For this article, here’s the design we’re going to create the interface below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/desktop-design-to-recreate.png" alt="Image" width="600" height="400" loading="lazy">
<em>desktop design to recreate</em></p>
<p>To begin, create a couple of <code>divs</code> in your markup.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"grid"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item"</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">"item"</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">"item"</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">"item"</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">"item"</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">body</span>&gt;</span>
</code></pre>
<p>Then utilize the <code>grid</code> property, <code>grid-template-columns</code>, and <code>grid-template-rows</code> to define the number of rows and columns you desire.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.grid</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">hsl</span>(<span class="hljs-number">36</span>, <span class="hljs-number">100%</span>, <span class="hljs-number">99%</span>);
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">1500px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">1000px</span>;
  <span class="hljs-attribute">display</span>: grid;
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">1.5vw</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1vw</span>;
  <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">6</span>, <span class="hljs-number">1</span>fr);
  <span class="hljs-attribute">grid-template-rows</span>: auto;
}
</code></pre>
<p>The final ingredient to achieving a bento-style grid lies in the use of the <code>grid-template-areas</code> property which is used to name grid areas according to the position you want them to occupy on the page.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.grid</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">hsl</span>(<span class="hljs-number">36</span>, <span class="hljs-number">100%</span>, <span class="hljs-number">99%</span>);
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">1500px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">1000px</span>;
  <span class="hljs-attribute">display</span>: grid;
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">1.5vw</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1vw</span>;
  <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">6</span>, <span class="hljs-number">1</span>fr);
  <span class="hljs-attribute">grid-template-rows</span>: auto;
  <span class="hljs-attribute">grid-template-areas</span>:
    <span class="hljs-string">"hero hero hero hero aside2 aside2"</span>
    <span class="hljs-string">"hero hero hero hero aside2 aside2"</span>
    <span class="hljs-string">"hero hero hero hero aside2 aside2"</span>
    <span class="hljs-string">"hero hero hero hero aside2 aside2"</span>
    <span class="hljs-string">"aside3 aside3 aside4 aside4 aside5 aside5 "</span>;
}
</code></pre>
<p>Finally, assign those names to the exact element you want to take up that space.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.item</span> {
  <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid <span class="hljs-number">#464545</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
}

<span class="hljs-selector-class">.grid</span> <span class="hljs-selector-class">.item</span><span class="hljs-selector-pseudo">:nth-child(1)</span> {
  <span class="hljs-attribute">grid-area</span>: hero;
}
<span class="hljs-selector-class">.grid</span> <span class="hljs-selector-class">.item</span><span class="hljs-selector-pseudo">:nth-child(2)</span> {
  <span class="hljs-attribute">grid-area</span>: aside2;
}

<span class="hljs-selector-class">.grid</span> <span class="hljs-selector-class">.item</span><span class="hljs-selector-pseudo">:nth-child(3)</span> {
  <span class="hljs-attribute">grid-area</span>: aside3;
}
<span class="hljs-selector-class">.grid</span> <span class="hljs-selector-class">.item</span><span class="hljs-selector-pseudo">:nth-child(4)</span> {
  <span class="hljs-attribute">grid-area</span>: aside4;
}

<span class="hljs-selector-class">.grid</span> <span class="hljs-selector-class">.item</span><span class="hljs-selector-pseudo">:nth-child(5)</span> {
  <span class="hljs-attribute">grid-area</span>: aside5;
}
</code></pre>
<p>You should have this result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/01-Bento-structure-achieved-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Bento structure achieved</em></p>
<p>All that’s left is to fill the boxes with their appropriate content and assets. You can some assets/content in this <a target="_blank" href="https://github.com/Daiveedjay/Bento/tree/main/images">repo</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/02-Bento-with-content-filled.png" alt="Image" width="600" height="400" loading="lazy">
<em>Bento Grid with its content filled</em></p>
<p>Another usefulness of the <code>grid-template-areas</code> property is the ease by which you can achieve responsiveness with it. In our example, to make the page responsive, you pass in a new string pair on your preferred threshold.</p>
<p>On tablet screens:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@media</span> screen <span class="hljs-keyword">and</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">1000px</span>) {
  <span class="hljs-selector-class">.grid</span> {
    <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">4</span>, <span class="hljs-number">1</span>fr);
    <span class="hljs-attribute">grid-template-areas</span>:
      <span class="hljs-string">"hero   hero   hero   hero"</span>
      <span class="hljs-string">"hero   hero   hero   hero"</span>
      <span class="hljs-string">"aside2 aside2 aside2 aside3"</span>
      <span class="hljs-string">"aside4 aside4 aside5 aside5"</span>;
  }
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/03-Tablet-screens.png" alt="Image" width="600" height="400" loading="lazy">
<em>Tablet Screens</em></p>
<p>And on smaller screens:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@media</span> screen <span class="hljs-keyword">and</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">750px</span>) {
  <span class="hljs-selector-class">.grid</span> {
    <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">3</span>, <span class="hljs-number">1</span>fr);
    <span class="hljs-attribute">grid-template-areas</span>:
      <span class="hljs-string">"hero   hero   hero"</span>
      <span class="hljs-string">"hero   hero   hero"</span>
      <span class="hljs-string">"aside2 aside2 aside2"</span>
      <span class="hljs-string">"aside3 aside3 aside3"</span>
      <span class="hljs-string">"aside4 aside4 aside4"</span>
      <span class="hljs-string">"aside5 aside5 aside5"</span>;
  }
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/04-Smaller-screens.png" alt="Image" width="600" height="400" loading="lazy">
<em>Smaller screens</em></p>
<h2 id="heading-common-rules-of-bento-grids">Common Rules of Bento Grids</h2>
<p>Here are some good rules of thumb when building bento grids:</p>
<ul>
<li><strong>Group Related Content</strong>: One of the fundamental principles of bento grids is to group related content together within each segment. This enhances the user's ability to quickly locate and understand the information they're seeking. By organizing content logically, designers can improve user engagement and satisfaction.</li>
<li><strong>Vary Box Sizes</strong>: Avoid using the same size for every box within the grid. Varying box sizes can create visual interest and hierarchy, drawing attention to key elements while maintaining overall balance. This variation can help guide users through the content and highlight important information effectively.</li>
<li><strong>Establish Visual Hiererchy</strong>: Although varying box sizes contribute to visual hierarchy, establishing visual hierarchy encompasses a broader range of design elements. In addition to box sizes, designers should consider factors such as colour, typography, and placement to prioritize certain elements over others.</li>
<li><strong>Prioritize Center Square</strong>: In traditional bento grids, the center square often holds a special significance and acts as a focal point. Designers can use this central square to showcase critical information or highlight key features, effectively punctuating the grid and drawing users' attention to its core elements.</li>
<li><strong>Limit the Number of Boxes</strong>: To maintain clarity and avoid overwhelming users, it's recommended to use nine or fewer boxes within the bento grid. Limiting the number of boxes ensures that the layout remains manageable and facilitates easier navigation and comprehension for users.</li>
<li><strong>Consider Swirl Pattern</strong>: While not a strict rule, considering a swirl pattern can add an extra layer of visual interest to the bento grid design. This involves arranging content in a curved or swirling pattern within the grid, creating a dynamic and engaging layout that encourages exploration.</li>
</ul>
<h2 id="heading-additional-information">Additional Information</h2>
<p>I’d like to point out a couple of things in the article not highlighted.</p>
<ul>
<li>First and foremost, the article was inspired by <a target="_blank" href="https://x.com/itsdesignertom/status/1764856109754667243?s=20">Tom Geoco</a>’s video on bento grids.</li>
<li><a target="_blank" href="https://bentogrids.com/">BentoGrids</a> is an excellent resource for finding design inspiration if you’re interested. If you’re interested in the full code, here’s the repo, <a target="_blank" href="https://github.com/Daiveedjay/Bento">GitHub</a>, and the Live version. <a target="_blank" href="https://bentogrid.netlify.app/">Demo</a>.</li>
<li>The design inspiration for the grid we built was gotten from <a target="_blank" href="https://www.frontendmentor.io/challenges/news-homepage-H6SWTa1MFl">FrontEnd Mentor</a>.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Bento grids stand out as a significant trend in the modern web design landscape, offering a blend of aesthetic appeal and functional clarity. They represent a design ethos that values order, beauty, and user-centricity. </p>
<p>As web technologies evolve, the principles underlying bento grids will continue to inform best practices, encouraging designers to create experiences that are not only visually compelling but also intuitively navigable.</p>
<h3 id="heading-contact-information">Contact Information</h3>
<p>Want to connect or contact me? Feel free to hit me up on the following:</p>
<ul>
<li>Twitter / X: <a target="_blank" href="https://twitter.com/JajaDavid8">@jajadavid8</a></li>
<li>LinkedIn: <a target="_blank" href="https://www.linkedin.com/in/david-jaja-8084251b4/">David Jaja</a></li>
<li>Email: Jajadavidjid@gmail.com</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Variables in Figma – A Handbook for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ At Figma Config 2023, the Figma team unveiled a lot of new features – including variables. The launch of variables in Figma offers designers a new approach that helps them make their designs more flexible and adaptable.  In this tutorial, you'll lear... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/variables-in-figma-handbook/</link>
                <guid isPermaLink="false">66d03a3ba30d09f91d49b78b</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ figma ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Faith Olohijere ]]>
                </dc:creator>
                <pubDate>Fri, 15 Dec 2023 22:11:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/How-to-Use-Variables-in-Figma-cover--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>At Figma Config 2023, the Figma team unveiled a lot of new features – including variables. The launch of variables in Figma offers designers a new approach that helps them make their designs more flexible and adaptable. </p>
<p>In this tutorial, you'll learn what variables in Figma are, and how to create and implement different types of variables while designing in Figma.</p>
<h2 id="heading-prerequisites">Prerequisites:</h2>
<p>To get the most out of this handbook, it'll be helpful to have basic knowledge of how to use Figma and its features. But note that this is not necessary, as I wrote this handbook for everyone – irrespective of their individual level of knowledge. </p>
<p>This handbook is for everyone who is interested in learning more about variables, Figma, and design in general.</p>
<h2 id="heading-table-of-contents">Table of Contents:</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-are-variables">What are variables?</a></li>
<li><a class="post-section-overview" href="#heading-differences-between-variables-and-styles-in-figma">Differences between Variables and Styles in Figma</a></li>
<li><a class="post-section-overview" href="#heading-why-are-variables-important-to-the-design-process">Why are Variables Important to the Design Process?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-variables-in-figma">How to Create Variables in Figma</a><ul>
<li><a class="post-section-overview" href="#heading-how-to-create-colour-variables-in-figma">How to Create Colour Variables in Figma</a><ul>
<li><a class="post-section-overview" href="#heading-how-to-create-colour-variables-for-tokens">How to Create Colour Variables for Tokens</a></li>
<li><a class="post-section-overview" href="#heading-how-to-implement-colour-variables-in-your-designs">How to Implement Colour Variables in Your Designs</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-different-modes-with-variables">How to Create Different Modes with Variables</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-how-to-create-number-variables-in-figma">How to Create Number Variables in Figma</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-string-variables-in-figma">How to Create String Variables in Figma</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-boolean-variables-in-figma">How to Create Boolean Variable in Figma</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-how-to-use-variables-for-advanced-prototyping">How to Use Variables for Advanced Prototyping</a><ul>
<li><a class="post-section-overview" href="#heading-advanced-prototyping-with-number-variables">Advanced Prototyping with Number Variables</a></li>
<li><a class="post-section-overview" href="#heading-advanced-prototyping-with-boolean-variables">Advanced Prototyping with Boolean Variables</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-how-to-use-variables-for-developers-using-apis">How to Use Variables for Developers- Using APIs</a> </li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h1 id="heading-what-are-variables">What Are Variables?</h1>
<p>The word "variable" has a lot of definitions. The Oxford Dictionary defines the word variable as "not consistent or having a fixed pattern; liable to change." Another definition says "an element, feature, or factor that is liable to vary or change." </p>
<p>The definitions above simply tell us that variables are elements which are dynamic and prone to change. With these definitions, we can now define what a variable is in Figma. </p>
<p>In Figma, a variable stores reusable values like colour and text values that you can apply to different kinds of design properties and prototypes.</p>
<h2 id="heading-differences-between-variables-and-styles-in-figma">Differences between Variables and Styles in Figma</h2>
<p>Given the definition of variables above, you might have begun to see some similarities between variables and style guides. Although both features exist to make your work better, there are a few key differences to keep in mind:</p>
<ul>
<li>Variables are a more advanced feature, and they allow you to define and reuse values like colours, text, and spacing across your designs. On the other hand, styles are predefined sets of design properties such as text styles, colour styles, and effect styles.</li>
<li>Variables allow designs to change when used in various contexts, because of their dynamic nature, unlike styles. For example, you can change your designs from light mode to dark mode or have padding values change when designing for different devices. This makes variables useful for creating design systems with adaptable components.</li>
<li>Variables offer a more flexible design process in creating flexible design components, especially where you want to change values like button text or color on different instances of the same component. Styles are typically used for maintaining consistent design elements like button styles, text headings, or colour palettes.</li>
<li>Variables can store raw, single values, while styles store sets of values.</li>
</ul>
<h2 id="heading-why-are-variables-important-to-the-design-process">Why are Variables Important to the Design Process?</h2>
<p>Using variables is quite important for a number of reasons.</p>
<p>First, variables help maintain <strong>consistency</strong> across a design system. By defining variables for colors, typography, spacing, and other design elements, you ensure that these elements have a uniform appearance throughout your project. This consistency is crucial for branding and user experience.</p>
<p>Variables also make designs <strong>adaptable</strong>. Designers can quickly experiment with different values such as colour schemes or font sizes by adjusting the variables. This adaptability is valuable when creating designs for different platforms or devices.</p>
<p>Variables are also quite <strong>efficient</strong>. When a variable is updated, all instances of that variable in the design updates automatically. This saves time and effort, and eliminates the need to manually update every instance of a specific element.</p>
<p>Variables are particularly useful in large projects or design systems because of their <strong>scalability</strong> and <strong>ease of maintenance</strong>. They allow designers to scale their designs without losing control. </p>
<p>Since projects grow and design systems evolve over time, variables can be adjusted globally to accommodate new requirements. Variables also provide a central place to update these changes, ensuring that all design elements are consistently modified.</p>
<p>And finally, variables can be beneficial to developers during the <strong>hand-off process</strong>. Designers can provide developers with precise values for design elements, reducing the chances of misinterpretation and streamlining the implementation process. </p>
<h1 id="heading-how-to-create-variables-in-figma">How to Create Variables in Figma</h1>
<p>Variables are quite easy to create in Figma. Below, I'll walk you through the steps for creating different kinds of variables in Figma.</p>
<p>At the moment, we have four types of variables in Figma:</p>
<ul>
<li>Color: used for colour fills.</li>
<li>Number: used for dimensions, corner radius, and auto layout properties.</li>
<li>String: used for text layers and variant properties.</li>
<li>Boolean: used to toggle layer visibility.</li>
</ul>
<p>We'll create and implement each of these variables in Figma, and also use them for advanced prototyping.</p>
<h2 id="heading-how-to-create-colour-variables-in-figma">How to Create Colour Variables in Figma</h2>
<p>The first type of variable we'll be creating is a colour variable. As a designer or developer, you have likely used colours in your projects. So, the concept of colour shouldn't be unfamiliar to you from a design standpoint.</p>
<h3 id="heading-step-1-open-a-new-figma-file">Step 1: Open a new Figma file</h3>
<p>Let's assume that you want to create colour variables for a new design project you're going to start working on, like a magazine website for example. The first thing you need to do is open a new Figma file.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/Variable-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Blank Figma file</em></p>
<h3 id="heading-step-2-choose-a-colour-palette">Step 2: Choose a colour palette</h3>
<p>The next step is to choose a colour palette for the project. Every design project has a set of colours used repeatedly to establish consistency – for example, for headers and backgrounds, to call attention to a primary button, and so on. </p>
<p>You'll want to choose colours which complement each other for your design. If you need some help here, you can read my article on the <a target="_blank" href="https://www.freecodecamp.org/news/the-60-30-10-rule-in-design/">60-30-10 rule in design</a>. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/Variable-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a colour palette</em></p>
<h3 id="heading-step-3-create-variables-for-each-colour">Step 3: Create variables for each colour</h3>
<p>Next, we'll create variables for each colour code in the palette. Go to the panel on the right-hand side and click on <em>local variables</em>.</p>
<p>Local variables means all the variables located in the design file.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-4.png" alt="Image" width="600" height="400" loading="lazy">
<em>Click on local variables</em></p>
<p>Click on <em>create variable</em> to create the first variable in the file. </p>
<p>A dropdown will appear containing the four types of variables I explained earlier. Since we're trying to create colour variables in this section, we'll choose <em>color</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-5.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create a colour variable</em></p>
<p>A created variable section will come up, with two columns: the title of the variable (<em>Color</em>), and the value of the variable (the colour code-FFFFFF).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/Variable-6.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choose colour variables</em></p>
<p>Give your new variable a name – you can use the role of the colour, primary background for instance. In the next column, type the colour code or use a colour picker. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-7.png" alt="Image" width="600" height="400" loading="lazy">
<em>Rename variable &amp; type in colour code</em></p>
<p>And there you go – you just created your first colour variable!</p>
<p>To see more editing options, hover over the variable's row. An <em>edit variable</em> icon will pop up.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-141.png" alt="Image" width="600" height="400" loading="lazy">
<em>Edit variable</em></p>
<p>Click on it to edit the colour variable to your taste.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-8.png" alt="Image" width="600" height="400" loading="lazy">
<em>Edit the colour variable/add a description</em></p>
<p>In the editing section, you can add a description on how to use the variable, hide from publishing, and so on.</p>
<p>Having done that, follow the steps above to create variables for the remaining colours in the colour palette.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-10.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create variables for other colours</em></p>
<p>You can also organise your variables into groups. To do this, select the colour variables you want to group (hold down SHIFT key), and right-click.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-11.png" alt="Image" width="600" height="400" loading="lazy">
<em>Group the colour variables</em></p>
<p>This will bring out some options:</p>
<ul>
<li>New group with selection</li>
<li>Edit variables</li>
<li>Duplicate variables</li>
<li>Delete variables</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-12.png" alt="Image" width="600" height="400" loading="lazy">
<em>New group with selection</em></p>
<p>Choose <em>New group with selection</em>, double-click on the group name, and rename it to <em>color/blue</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-14-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Rename group</em></p>
<p>You can group your colour variables anyway you'd like to – for example, background colours, header colours, different shades of a particular colour, and so on.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-15.png" alt="Image" width="600" height="400" loading="lazy">
<em>Colour blue variables grouped.</em></p>
<p>Violà! You just created a colour variable group in Figma. Click on the collection drop-down and choose <em>rename collection</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-16.png" alt="Image" width="600" height="400" loading="lazy">
<em>Rename collection</em></p>
<p>You can rename this collection <em>primitives</em>. </p>
<p><em>Primitives</em> means basic. Also, you can decide to rename your collections or not. The choice rests on you.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-39.png" alt="Image" width="600" height="400" loading="lazy">
<em>Renamed primitives collection</em></p>
<h3 id="heading-how-to-create-colour-variables-for-tokens">How to Create Colour Variables for Tokens</h3>
<p>Now, we'll create colour variables for the text, surfaces (such as backgrounds), and borders we need for the project. We want to assign different functions to the colour palette (variables) we created earlier.</p>
<p>Click on local variables and create a new collection. You can name this <em>tokens</em>. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-21.png" alt="Image" width="600" height="400" loading="lazy">
<em>New collection</em></p>
<p>Create a new colour variable and rename it "primary text". </p>
<p>In order to save yourself time, and group your variables as you're naming them, rename the variable as <em>text/primary</em>. This will automatically form a group.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-24.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating and grouping text variables</em></p>
<p>Click on the fill box and go to <em>Libraries</em> to see all colour variables created.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-26.png" alt="Image" width="600" height="400" loading="lazy">
<em>Assigning colour from libraries</em></p>
<p>We'll choose <em>Main Black</em> which is under <em>color/greys</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-27.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing colour black</em></p>
<p>We can go ahead and assign other colour variables for different text functions, as much as we want to. Remember to add <em>text/</em> before the actual name of the variable, so it'll form a group automatically.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-28.png" alt="Image" width="600" height="400" loading="lazy">
<em>Assigning colour variables for text</em></p>
<p>Next, we'll create colour variables for surfaces such as backgrounds, and for borders as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-29.png" alt="Image" width="600" height="400" loading="lazy">
<em>Colour variables for surfaces and borders</em></p>
<p>Some of the colour variables might bear the same colour code, but they have different functions, so that's totally fine. For example, the colour code for button text is the same as the colour code for main background. </p>
<h3 id="heading-how-to-implement-colour-variables-in-your-designs">How to Implement Colour Variables in Your Designs</h3>
<p>Next, we're going to implement these colour variables in our design. </p>
<p>In the image below, there are four mobile wireframes with no colour and images (I created these previously). </p>
<p>You can read about how to create wireframes in this article: <a target="_blank" href="https://www.freecodecamp.org/news/what-is-wireframing/">What is Wireframing? How to move from Paper Sketches to High Fidelity Wireframes</a>.</p>
<p>We'll use the colour variables we've created to add colour to the buttons and text, making sure all elements are consistent.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-30.png" alt="Image" width="600" height="400" loading="lazy">
<em>Low-fidelity wireframes</em></p>
<p>Starting with the first screen, let's add colour to the button. Click on the button, and go to to <em>Fill</em> on the right-hand side of your screen. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-32-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Click on button</em></p>
<p>In the <em>Fill</em> section, click on <em>style</em> (the four dot icon by the side). Selecting <em>style</em> will bring up a list of colours in your libraries. Select the colour you've assigned for the primary button in order to implement it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-33-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Select a fill colour from the colour variables in libraries</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-34-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Implemented button colour</em></p>
<p>Next, give the button text a white colour following the same steps.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-35-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>Implementing colour variable for button text</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-36-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Implemented button text colour</em></p>
<p>You can go ahead and do the same for the other screens, following the steps above. Don't forget to update the text and colours as well. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-37-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Updating colour variables for other screens</em></p>
<p>You can also add some images or illustrations to complete the look.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/variable-38-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding illustrations to updated design</em></p>
<p>Note: You can get your illustrations from plugins in Figma like Storyset by Freepik, Artify Illustrations, and so on, as well as from illustration libraries like <a target="_blank" href="https://www.freepik.com/">Freepik</a>, <a target="_blank" href="https://www.lapa.ninja/blog/free-illustrations-library-for-your-project/">Lapa Ninja</a>, and others.</p>
<h3 id="heading-how-to-create-different-modes-with-variables">How to Create Different Modes with Variables</h3>
<p>Next, we'll create different modes for our design. For instance, if you're working on a project that requires light and dark modes, instead of changing all the design elements manually to accommodate the modes, you can simply use variables to implement that.</p>
<p>To start with, click on <em>Local variables</em> to create a new variable. A list of all variables in the file and their groups will come up:</p>
<p>color/blue:</p>
<ul>
<li>Primary Button</li>
<li>Main Blue</li>
</ul>
<p>color/greys:</p>
<ul>
<li>Main Black</li>
<li>Main Background</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-142.png" alt="Image" width="600" height="400" loading="lazy">
<em>Opening "Local variables"</em></p>
<p>Next, I'll create a new collection so I can just focus on the modes I am about to create. To create a new collection, simply click on the menu icon on the variables header.</p>
<p>Note that creating a new collection isn't mandatory. It's just to help take your focus away from other variables you have already created.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-143.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a new collection</em></p>
<p>Next, I'll rename the collection to <em>Modes.</em> To rename a collection, simply double-click on the title, and input your preferred title.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-144.png" alt="Image" width="600" height="400" loading="lazy">
<em>Renaming a collection</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-145.png" alt="Image" width="600" height="400" loading="lazy">
<em>Renamed collection "Modes"</em></p>
<p>Next, click on <em>Create variable</em> to create a new variable. I'll choose <em>Color</em> because that's the variable we're working with.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-146.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a variable called Color</em></p>
<p>The created colour variable will come up with a default colour code: FFFFFF.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-147.png" alt="Image" width="600" height="400" loading="lazy">
<em>Created color variable with default colour code: FFFFFF</em></p>
<p>Next, I'll rename the variable <em>Background</em> because I'm trying to set the background colours for each mode (light and dark).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-148.png" alt="Image" width="600" height="400" loading="lazy">
<em>Renamed color variable: Background</em></p>
<p>Now, we've been working with only the name and value of the variables we've created, but we can add another column when we want to create modes. To do this, simply click on the plus icon on the header to add a new variable mode.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-149.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the plus icon</em></p>
<p>The new mode will come with three columns: </p>
<ul>
<li>Column 1 (the title of the variable – Background)</li>
<li>Mode 1 (the first value of the variable – colour code FFFFFF)</li>
<li>Mode 2 (the first value of the variable – colour code FFFFFF)</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-150.png" alt="Image" width="600" height="400" loading="lazy">
<em>Created new mode</em></p>
<p>Next, I'll rename the modes to light and dark. To do this, simply double-click on the title and edit the name.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-151.png" alt="Image" width="600" height="400" loading="lazy">
<em>Renamed modes: Light &amp; Dark</em></p>
<p>Now, we'll assign a value to the background for dark mode. To do this, simply input the colour code/value you prefer for the background. I'll use #0C3272 as my background colour for dark mode.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-152.png" alt="Image" width="600" height="400" loading="lazy">
<em>Changed value for dark mode background</em></p>
<p>Next, we'll create other colour variables for other elements like, text, button colour, button text colour, and so on for the two modes. I''ll list out the specifications to make it easier:</p>
<p><strong>Light/Dark:</strong></p>
<ul>
<li>Body text: 1A1A1A/FFFFFF</li>
<li>Button: 0C3272/FFFFFF</li>
<li>Button text: FFFFFF/0C3272</li>
<li>iPhone header: 1A1A1A/FFFFFF</li>
</ul>
<p>Next, we'll go ahead to create the variables. Just follow the steps we followed earlier to create the variables and assign values for each of the modes.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-154.png" alt="Image" width="600" height="400" loading="lazy">
<em>Created variables for other elements</em></p>
<p>Next, we make sure the design is connected to the variables we created. To do this, simply hold the element and use <em>Fill</em> to tie it to the colour variable. </p>
<p>For the Button text for instance, select the text, and click on the style icon in <em>Fill</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-155.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on style icon in the "FFill" section</em></p>
<p>Next, scroll down the list that comes up, to the specific variable you want to tie the variable to (in this case Body text).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-156.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting Body text variable.</em></p>
<p>Do the same for the other elements in the design, including the background.</p>
<p>Note that I'll be leaving the illustrations the way they are.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-157.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screens connected to the variable modes.</em></p>
<p>To check if the modes actually work, click on the <em>change variable mode</em> icon on the <em>Layer</em> section on the right-hand panel of your screen. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-158.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the "change variable mode" icon</em></p>
<p>A list of all modes (Light &amp; Dark) will come up and you can switch the screen to whatever mode you choose.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-159.png" alt="Image" width="600" height="400" loading="lazy">
<em>Switching modes</em></p>
<p>A section named <em>Modes</em> will appear on the <em>Layer</em> section, indicating that one of the screens is in dark mode.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-160.png" alt="Image" width="600" height="400" loading="lazy">
<em>One dark mode &amp; one light mode screen.</em></p>
<h2 id="heading-how-to-create-number-variables-in-figma">How to Create Number Variables in Figma</h2>
<p>Next, I'll show you how to create number variables in Figma. </p>
<p>Number variables are defined by number values, and they can be applied to corner radius, width or height padding, and so on. Here are the steps to follow to create your own:</p>
<h3 id="heading-step-1-choose-a-variable">Step 1: Choose a variable</h3>
<p>Just like we did when creating color variables, click on the local variables panel to select the kind of variable you're trying to create. Here, you'll select <em>number.</em> </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/variable-40.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing variable to create</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Variable-41.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting "number"</em></p>
<p>When you select <em>number</em>, it appears on the list of variables with a value, in this case 0. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-43.png" alt="Image" width="600" height="400" loading="lazy">
<em>Number variable showing Number with a default value of 0</em></p>
<p>Now, you can rename the number variable to whatever you decide. To rename the variable, double click on <em>number</em>, and change it to whatever name you want.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-44.png" alt="Image" width="600" height="400" loading="lazy">
<em>Renaming number variable</em></p>
<p>I'll rename mine to <em>OrderCount,</em> because I'm trying to implement a function that allows a user to increase the number of portions of food they're trying to order.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-45.png" alt="Image" width="600" height="400" loading="lazy">
<em>Renamed number variable</em></p>
<p>Next, we'll set the default number value to <em>1</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-46.png" alt="Image" width="600" height="400" loading="lazy">
<em>Setting default number value</em></p>
<p>Now we'll tie the number on the design to the number variable (<em>OrderCount).</em> To do this, click on the number in the design.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-47.png" alt="Image" width="600" height="400" loading="lazy">
<em>Implementing the number variable</em></p>
<p>Then go to <em>Text</em> on the left hand side of your screen. Click on the <em>Apply variable</em> icon to apply the variable.</p>
<p>Note: The <em>apply variable</em> icon will only appear on the <em>Text</em> section when a variable has been created.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-49.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the "appy variable" icon</em></p>
<p>Clicking on the icon will bring up a list of all number variables available in the file. Next, you'll select the variable you're trying to implement. I'll choose <em>OrderCount</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-50.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting a number variable</em></p>
<p>When the variable has been implemented (tied to the number), it'll appear on the text section, indicating that a number variable has been implemented.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-51.png" alt="Image" width="600" height="400" loading="lazy">
<em>Implemented number variable</em></p>
<p>Now, we'll also need two more number variables for the other number values in the design (cost of food and total cost). This is so that these values will also change when a user increases the number of portions they're ordering. </p>
<p>We won't include delivery fee, because it remains the same way irrespective of the number of portions a user orders.</p>
<p>Next, we'll follow the same process as we did above to create number variables for these.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-52.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating other number variables</em></p>
<p>Next, we'll tie the numbers in the design to their respective number variables, just as we also did earlier. </p>
<p>Note: In the main design, I gave the actual number (25) a different frame from the dollar sign (which is in text). This is because when creating the number variable, the dollar sign will not be attached, because it's a word, not a number. </p>
<p>Consequently, when I tie the number variable to the design, I'll be applying it to the frame containing the number alone.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-53.png" alt="Image" width="600" height="400" loading="lazy">
<em>Give the number a different frame from the dollar sign</em></p>
<p>So, when I tied the first number to the number variable I created (Cost-Portion), something interesting happened. The number in the design took on the value of the variable. Instead of 25.00 which was in the screen earlier, it changed to just 25 because that's what the number variable was set to. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-55.png" alt="Image" width="600" height="400" loading="lazy">
<em>Number variable changing the number in the design</em></p>
<p>Now, to avoid any unpleasantness, I'll change the values of the other numbers, and realign them.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-56.png" alt="Image" width="600" height="400" loading="lazy">
<em>Changed and realigned number values in the design</em></p>
<p>We've just created number variables for our design. In the section for advanced prototyping, we'll check to see if these number variables actually work.</p>
<h2 id="heading-how-to-create-string-variables-in-figma">How to Create String Variables in Figma</h2>
<p>Next, you'll learn how to create string variables in Figma.  </p>
<p>As I wrote earlier, string variables are used for text layers and variant properties. With string variables, you can change the headings in your design, flip text on different screens, change language modes, and so on.</p>
<p>For this article, we'll use string variables to change the headings on the screens for each mode we created earlier (light and dark). </p>
<p>As usual, our first step is to click on <em>Local variables</em> and select the type of variable we want to create.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-161.png" alt="Image" width="600" height="400" loading="lazy">
<em>Going to local variables to create a new variable</em></p>
<p>I'll choose <em>String</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-163.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing "String" out of a list of all variables</em></p>
<p>When I do that, the string variable I just created will appear on the list of variables.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-164.png" alt="Image" width="600" height="400" loading="lazy">
<em>Created String variable</em></p>
<p>If you noticed, the string variable has two columns for "string value", because I created the variable in the <em>Modes</em> collection. Following that, let's see if we can change the headings for each mode. </p>
<p>Note: The string value is the actual text you're trying to change. </p>
<p>So, for the first screen whose heading is "Transactions Made Easy", I want it to change to "Easy Transactions, Less Stress" for dark mode. For the second screen whose heading is "Pay Bills with Ease", I want it to change to  "Paid Bills, Easier Life" for dark mode.</p>
<p>Since we're changing the headings for two different screens, we'll create another string variable.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-165-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating another string variable</em></p>
<p>Next, we'll input the different values for the different modes. To do this, just input the different texts for the two screens in both modes.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-166-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Inputing string value</em></p>
<p>Next, we'll tie the headings to the string variables we just created. To do this, click on the particular heading, and go to the <em>Apply variable</em> icon on the <em>Text</em> section.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-167-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>Applying string variable</em></p>
<p>Next, scroll down and choose the string you're applying it to.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-168-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing string variable</em></p>
<p>Once you're done, a string icon will come up, indicating that a string variable was applied to the text.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-169-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Applied string variable</em></p>
<p>Do the same for the second string:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-170-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Applying string variable to the second screen</em></p>
<p>Next, let's test to see if the string variable works. Select the screens which have the applied variable, go to <em>Layers,</em> and change the mode from light to dark.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-171-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting screens which have the applied variables</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-172-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting dark mode</em></p>
<p>Mine works:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-173-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screens changed to dark mode</em></p>
<h2 id="heading-how-to-create-boolean-variables-in-figma">How to Create Boolean Variables in Figma</h2>
<p>Next up, we'll learn how to create Boolean variables. </p>
<p>Generally, boolean variables are variables that can only have two possible values – true or false. In Figma, boolean variables have the same function: they are used for variant properties or components with two values: true or false. </p>
<p>Remember the toggle in the design above? </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-110.png" alt="Image" width="600" height="400" loading="lazy">
<em>Toggle in the design used for implementing number variables</em></p>
<p>I'll change that to a checkbox and use boolean variables to make it work. </p>
<p>To do this, I'll copy out the component and paste it on another frame. I'll then add the checkbox (and replace it in the main design screen later).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-111.png" alt="Image" width="600" height="400" loading="lazy">
<em>Checkbox on a blank frame.</em></p>
<p>Next, we'll make the selection a variant. To do this, double-click on the <em>Create component</em> icon on your Figma file header.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-113.png" alt="Image" width="600" height="400" loading="lazy">
<em>Double-clicking on "create component" icon</em></p>
<p>A variant will automatically appear:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-114.png" alt="Image" width="600" height="400" loading="lazy">
<em>Variant of the component</em></p>
<p>Next, I'll create different states for the checkboxes: default, hover, and filled.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-116.png" alt="Image" width="600" height="400" loading="lazy">
<em>Different states for the chechboxes: Default, hover and filled.</em></p>
<p>Now, we'll create the boolean variable. </p>
<p>To do this, go to <em>Local variables</em> as usual and select <em>Boolean</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-118.png" alt="Image" width="600" height="400" loading="lazy">
<em>Opening local variables</em></p>
<p>Click on <em>Create variable</em>. </p>
<p>Next, we'll choose <em>Boolean</em> from the list.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-117.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing "boolean" from the list</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-119.png" alt="Image" width="600" height="400" loading="lazy">
<em>Created boolean variable</em></p>
<p>Next, we'll rename the boolean variable <em>SaveFood</em> since we're trying to create a function for saving a food choice for subsequent orders.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-120.png" alt="Image" width="600" height="400" loading="lazy">
<em>Renamied boolean variable</em></p>
<p>Next, we'll make the variable <em>True</em> by default. To do this, just click on the toggle icon by the side of the variable.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-121.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You've created a boolean variable!</p>
<p>We'll create an interaction for this boolean variable in the advanced prototyping section and check if it works. </p>
<h2 id="heading-how-to-use-variables-for-advanced-prototyping">How to Use Variables for Advanced Prototyping</h2>
<p>In this section, we'll learn how to use variables for advanced prototyping in Figma, using the colour, number, string, and boolean variables we implemented earlier in the design.</p>
<p>N.B: You can only use advanced prototyping features on Figma if your file is on a paid team file. If you don't have a paid team version, you can apply for the <em><a target="_blank" href="https://www.figma.com/education/">Figma for Education</a></em> plan. It's a way Figma helps learners and educators by giving them access to resources, and all benefits of a paid version, for free.</p>
<p>You can use advanced prototyping when you have a lot of screens to work on, and to simply make prototyping easier.</p>
<h3 id="heading-advanced-prototyping-with-number-variables">Advanced Prototyping with Number Variables</h3>
<p>Starting with the number variables we created above, let's try to check if it actually works. But before we do that, we'll have to actually prototype the design. </p>
<p>Note that you can prototype number variables for designs where your user can increase or decrease the number of an item on the screen. Prototyping helps to show the functionality and how that particular feature would work. </p>
<p>To start with, I'll make the frame where the order count is a component. To do this, select the frame, and click on the component icon on your Figma file header.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-57.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting the order count frame</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-58.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the component icon</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-59.png" alt="Image" width="600" height="400" loading="lazy">
<em>The order count component</em></p>
<p>Click on the component icon again to make it a variant.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-60.png" alt="Image" width="600" height="400" loading="lazy">
<em>Making the order count component a variant</em></p>
<p>I'll make a frame outside the screen and drag the variant there, so I'll be able to work on the interactions well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-61.png" alt="Image" width="600" height="400" loading="lazy">
<em>Making a frame outside the screen</em></p>
<p>Remember that we want to implement a function where the number of portions increases when the user clicks on the plus icon. </p>
<p>We'll start prototyping from here. </p>
<p>Now, click on the plus icon in the default variant and move to the prototype tab.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-62.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the plus icon in the default variant</em></p>
<p>Next, click on the plus icon in the interactions area to add an interaction.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-63.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding an interaction</em></p>
<p>A tab will come up showing interactions. In this case, it's set to default <em>On click</em>, and no interaction has been added yet (None).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-64.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding an interaction</em></p>
<p>Now, click on the dropdown icon that says <em>None.</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-65.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the dropdown icon</em></p>
<p>It'll bring up a list:</p>
<ul>
<li>Navigate to</li>
<li>Change to</li>
<li>Back</li>
<li>Set variable</li>
<li>Conditional</li>
<li>Scroll to</li>
<li>Open link</li>
<li>Open overlay</li>
<li>Swap overlay</li>
<li>Close overlay</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-66.png" alt="Image" width="600" height="400" loading="lazy">
<em>List following the dropdown</em></p>
<p>Choose <em>Set variable</em>. </p>
<p>A list of all variables in the file will come up, and you can then select the particular variable you want to implement. I'll click on <em>OrderCount</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-67.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing "set variable"</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-68.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on Order Count (the first time)</em></p>
<p>Next, I'll click on <em>OrderCount</em> again to write a mathematical expression, and all the available mathematical expressions will appear:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-69.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on Order Count (the second time) and showing all mathematical expressions</em></p>
<p>I'll select <em>Addition</em>, because that's what we're trying to do.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-70.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing the "addition" expression</em></p>
<p>You'll notice that an addition icon popped up to signify that the addition expression was given. </p>
<p>Next, I'll input <em>1</em> by the side of the addition icon to show that it's plus 1.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-71.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding number 1 to the expression</em></p>
<p>Done! </p>
<p>Now, we'll follow the same steps to do the same for the minus icon, making the expression subtraction instead of addition.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-72.png" alt="Image" width="600" height="400" loading="lazy">
<em>Added interactions for the minus icon</em></p>
<p>Done!</p>
<p>Note: We don't really need the variant we created earlier. You might only use the variant in cases where you want to create a hover state. I just wanted to show you how easy it would be to create a variant while doing this. </p>
<p>Next, we'll just copy the prototyped component and put it back in the main design.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-73.png" alt="Image" width="600" height="400" loading="lazy">
<em>Frame containing the prototyped variable</em></p>
<p>To put the prototyped component in the main design, click on <em>Assets</em> at the top of the left hand panel.</p>
<p>This section will show all the assets in the page you're currently on.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-74.png" alt="Image" width="600" height="400" loading="lazy">
<em>Showing all assets on the page</em></p>
<p>Next, I'll drag the frame to the design. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-75.png" alt="Image" width="600" height="400" loading="lazy">
<em>Dragged asset to main design</em></p>
<p>Note: If you don't want to follow the process above to place the prototyped component in the design, simply copy the component (CTRL + C), and <em>paste to replace</em> the frame on the main design.</p>
<p>Now, let's check our prototype out. To do this, you don't need to open the prototype on another tab. You can simply click on the asset and press SHIFT + space bar.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-76.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicked asset</em></p>
<p>Another frame will appear on your screen. It's interactive and you can test your prototype on it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-77.png" alt="Image" width="600" height="400" loading="lazy">
<em>Interactive frame on your Figma screen.</em></p>
<p>Try clicking on the minus and plus icons on the frame to see if it carries out its function. </p>
<p>After checking the prototype, I'd like to implement some logic. </p>
<p>We don't want a scenario where the clicking on the minus icon continues till after 0 and now gives us a negative sign like -1 as you can see in the image below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-78.png" alt="Image" width="600" height="400" loading="lazy">
<em>Minus icon giving us negative values</em></p>
<p>That wouldn't make sense, so we'll add a <em>conditional</em>. </p>
<p>A conditional is simply a condition that sets rules about how the interaction should work.</p>
<p>To do this, I'll move to the frame containing the component I made earlier. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-79.png" alt="Image" width="600" height="400" loading="lazy">
<em>Frame containing prototyped component</em></p>
<p>I'll be adding the conditional to the minus icon since that's the area that would give us negative values. So, I want the values to stop at 1 since that's the least a user can order (they can't order half or 0, for example). </p>
<p>So, we'll just zoom into the component to add our conditional. Make sure you're on the prototype tab as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/variable-80.png" alt="Image" width="600" height="400" loading="lazy">
<em>Moving to prototype tab and zooming in on the prototyped component</em></p>
<p>I'll click on the variable icon by the minus frame.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-81.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting the variable icon close to the minus icon frame</em></p>
<p>This will bring up the already set interactions:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-82.png" alt="Image" width="600" height="400" loading="lazy">
<em>Already made interactions on the minus frame</em></p>
<p>Next, I'll click on the plus icon by the 'x' on the interactions header.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-83.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the plus icon in the interaction header</em></p>
<p>I'll choose <em>conditional</em> from the list of options which will appear:</p>
<ul>
<li>Navigate to</li>
<li>Change to</li>
<li>Back</li>
<li>Set variable</li>
<li>Conditional</li>
<li>Scroll to</li>
<li>Open link</li>
<li>Open overlay</li>
<li>Swap overlay</li>
<li>Close overlay</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-84.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing conditional from the list of options</em></p>
<p>We'll then write the condition. To do this, click on <em>Write condition</em> by the <em>if else</em> statement<em>.</em> </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-86.png" alt="Image" width="600" height="400" loading="lazy">
<em>Writing a condition for the interaction</em></p>
<p>When we click on <em>Write condition</em>, a list of all number variables will come up. I'll choose <em>OrderCount</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-87.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting ordercount</em></p>
<p>This will bring up a list of all available conditions:</p>
<ul>
<li>Equal to</li>
<li>Not equal to</li>
<li>Greater than</li>
<li>Greater than or equal to</li>
<li>Less than</li>
<li>Less than or equal to</li>
</ul>
<p>I'll choose <em>Not equal to</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-88.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing "Not equal to" condition</em></p>
<p>Next, the icon for the condition I chose will appear on the input field for writing the condition.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-89.png" alt="Image" width="600" height="400" loading="lazy">
<em>Condition appearing on the input field</em></p>
<p>Next, I'll input 0, which means the interaction is not equal to 0.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-90.png" alt="Image" width="600" height="400" loading="lazy">
<em>Inputing 0 (zero)</em></p>
<p>Next, I'll close the frame and try moving the <em>Set variable</em> section under the <em>conditional section</em> in the interaction. To close the Set variable section, click on the little dropdown icon.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-91.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the dropdown icon to close set variable</em></p>
<p>When you click on the little dropdown icon, the <em>Set variable</em> section will be minimized, allowing you move the section under the <em>Conditional</em> section.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-92.png" alt="Image" width="600" height="400" loading="lazy">
<em>Closed set variable section</em></p>
<p>Next, I'll drag the <em>set variable</em> section under the <em>conditional</em> section. To do this, just hover on the <em>set variable</em> section and use your trackpad or mouse to drag it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-93.png" alt="Image" width="600" height="400" loading="lazy">
<em>Dragging set variable under conditional</em></p>
<p>We just added a conditional to our interaction! The icon for the minus frame will change to a condition icon, showing that a conditional has been added.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-94.png" alt="Image" width="600" height="400" loading="lazy">
<em>Added a conditional to minus interaction</em></p>
<p>Now, you can test this new interaction to see how it works. </p>
<p>Mine certainly does! It doesn't go lower than 0 anymore.</p>
<h3 id="heading-how-to-implement-cost-per-portion-variable">How to implement cost per portion variable</h3>
<p>Now, we want the other number values (cost per portion and total cost) to increase in response to the number of portions a user orders.</p>
<p>We'll start with the Plus icon frame:</p>
<p>Going back to the component we've been working on...</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-95.png" alt="Image" width="600" height="400" loading="lazy">
<em>Frame with prototyped component</em></p>
<p>I'll click on the plus frame and go ahead to <em>set variable</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-96.png" alt="Image" width="600" height="400" loading="lazy">
<em>Opening the interactions for plus frame</em></p>
<p>I'll click on the plus icon on the interactions header.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-97.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the plus icon on the interactions header</em></p>
<p>Next, I'll select <em>set variable</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-98.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting set variable</em></p>
<p>A list of all variables that have been created in the file will come up:</p>
<ul>
<li>The color variables for text, buttons, headings, and so on.</li>
<li>Number variables – <em>OrderCount</em>, <em>Cost-Portion</em>, and so on.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-99.png" alt="Image" width="600" height="400" loading="lazy">
<em>A list of all variables in the file</em></p>
<p>I'll scroll down to choose <em>cost-portion,</em> which is the cost per food portion a user orders.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-100.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing "Cost-portion" (the first time)</em></p>
<p>An input field to write an expression for the variable will come up.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-101.png" alt="Image" width="600" height="400" loading="lazy">
<em>Write expression input filed</em></p>
<p>To write an expression, click on Cost-Portion again and select <em>Addition</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-102.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing cost-portion (the second time) and selecting addition</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-104.png" alt="Image" width="600" height="400" loading="lazy">
<em>Addition icon coming up on input field</em></p>
<p>Next, I'll input 25, meaning that +25 should be added for every portion of food a user orders.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-103.png" alt="Image" width="600" height="400" loading="lazy">
<em>Inputing 25</em></p>
<p>Having added the interaction for the plus frame, we'll follow the same process for the minus frame. When you're done, the <em>Set variable</em> section should be under the <em>Conditional</em> section.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-105.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding interaction for the minus frame</em></p>
<p>Remember there's a conditional for the minus frame, so I'll just drag the new interaction inside the conditional.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-106.png" alt="Image" width="600" height="400" loading="lazy">
<em>Dragging the new "set variable" interaction inside the conditiona;</em></p>
<p>Now, try testing the new interaction you just added. Mine certainly works!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-107.png" alt="Image" width="600" height="400" loading="lazy">
<em>Testing the new interaction</em></p>
<p>Next, we still have one last variable to add (Total Cost). </p>
<p>Follow the steps above to recreate this interaction. Starting with the plus frame, implement the variable to make sure $25 adds when the order increases. It should show a placeholder – <em>Total Cost + 25</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-108.png" alt="Image" width="600" height="400" loading="lazy">
<em>Implementing Total Cost variable</em></p>
<p>Now, do the same for the minus frame and test the interaction. Don't forget to add the new interaction inside the conditional.</p>
<p>Mine works!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-109.png" alt="Image" width="600" height="400" loading="lazy">
<em>Testing the interactions</em></p>
<p>You just learnt how to implement number variables with advanced prototyping in Figma. Congrats!</p>
<h3 id="heading-advanced-prototyping-with-boolean-variables">Advanced Prototyping with Boolean Variables</h3>
<p>Next, we'll create an interaction for the boolean variable we created earlier in the article. </p>
<p>Note that you can prototype your boolean variables in designs where you have features like checkboxes and toggles. The prototype would show how the checkbox is supposed to function.</p>
<p>To create the interaction, move to the prototype tab and focus on the frame containing the boolean components.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-122.png" alt="Image" width="600" height="400" loading="lazy">
<em>Frame containing boolean components</em></p>
<p>Now, our main interaction will start from the hover state because that's when a user tries to click on the checkbox. But we still need to add an action that will take the user from the default state to the hover state. </p>
<p>To do this, I'll just click on the first variant and drag it to the second variant.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-132.png" alt="Image" width="600" height="400" loading="lazy">
<em>Connecting first variant to the second variant</em></p>
<p>I'll change <em>On-click</em> to <em>While Hovering</em>. To do this, just click on the <em>On-click</em> dropdown and select from the list that pops up:</p>
<ul>
<li>On click</li>
<li>On drag</li>
<li>While hovering</li>
<li>While pressing</li>
<li>Key/Gamepad</li>
<li>Mouse enter</li>
<li>Mouse leave</li>
<li>Mouse down</li>
<li>Mouse up</li>
<li>After delay</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-133.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the on-click dropdown</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-134.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting "while hovering" from the list</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-135.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selected "while hovering"</em></p>
<p>I also want to change <em>Instant</em> to <em>Smart Animate</em>, so I'll click on the dropdown icon by <em>Instant</em>, and select from the list that appears:</p>
<ul>
<li>Instant</li>
<li>Dissolve</li>
<li>Smart animate</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-136.png" alt="Image" width="600" height="400" loading="lazy">
<em>Changing "Instant" to "Smart Animate"</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-137.png" alt="Image" width="600" height="400" loading="lazy">
<em>How the interaction looks</em></p>
<p>So, we're done with the first interaction and we'll get started on connecting the second variant to the third variant (Hover - Filled).</p>
<p>Just as we did earlier, we'll just drag the second variant to the third variant.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-124.png" alt="Image" width="600" height="400" loading="lazy">
<em>Connecting the second to the third variant</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-125-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>How the interaction looks</em></p>
<p>Like I said earlier, the main interaction starts from the second variant so we'll not be following the same steps we took to add the first interaction.</p>
<p>To continue, I'll click on the plus icon on the interaction header to add an action, and select <em>Set variable</em> from the list that pops up:</p>
<ul>
<li>Navigate to</li>
<li>Change to</li>
<li>Back</li>
<li>Set variable</li>
<li>Conditional</li>
<li>Scroll to</li>
<li>Open link</li>
<li>Open overlay</li>
<li>Swap overlay</li>
<li>Close overlay</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-126.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the plus icon on the interaction</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-127.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing "set variable" from the list</em></p>
<p>Next, I'll click on <em>Pick target variable</em> to select the boolean variable.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-128.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on "pick target variable"</em></p>
<p>I'll scroll down the list of variables to choose the variable I want: SaveFood.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-129.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting "SaveFood" variable</em></p>
<p>Now, to write the expression for this variable, we're going to say the value will be equal to true. So, I'll select <em>True</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-130.png" alt="Image" width="600" height="400" loading="lazy">
<em>Writing the expression and selecting "true"</em></p>
<p>Having selected <em>True</em>, the expression (<em>true</em>) will go under the <em>SaveFood</em> variable, indicating that an expression was applied.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-131.png" alt="Image" width="600" height="400" loading="lazy">
<em>How the interaction looks</em></p>
<p>Next, we'll just copy the original component and paste it in our design so it can sync when we're checking the prototype.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-138.png" alt="Image" width="600" height="400" loading="lazy">
<em>Pasting the default component in the main design</em></p>
<p>To check the prototype directly on your Figma page, click on Shift + space bar.</p>
<p>Mine works!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-139.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>But I noticed something; I can't un-check the checkbox. No interaction was provided for that. Now, we'll quickly add that interaction so our component works perfectly. </p>
<p>To do this, we'll go back to our components, making sure we're in prototype mode, and drag the connection from filled all the way back to default.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Variable-140.png" alt="Image" width="600" height="400" loading="lazy">
<em>Dragging the connection from filled state to default state</em></p>
<p>Now, it's works perfectly!</p>
<h2 id="heading-how-to-use-variables-for-developers-using-apis">How to Use Variables for Developers – Using APIs</h2>
<p>Variables are very helpful for teams consisting of developers and/or designers. </p>
<blockquote>
<p>Variables are now supported in Figma’s Plugin API—for building plugins and widgets—and in the REST API. Since variables is currently in open beta, features and functions may change as we respond to feedback. – Figma Docs</p>
</blockquote>
<p>There are three documentations which contain support for variables for developers on Figma: </p>
<ul>
<li>For the <a target="_blank" href="https://www.figma.com/developers/api#variables">REST API</a>: </li>
</ul>
<blockquote>
<p>This API includes endpoints for querying, creating, updating, and deleting variables. – Figma docs</p>
</blockquote>
<p>To be able to use this API, you must be a member of an enterprise.</p>
<ul>
<li>For the <a target="_blank" href="https://www.figma.com/plugin-docs/working-with-variables/">plugin API</a>: </li>
</ul>
<blockquote>
<p>This API provides support for creating and reading variables, and binding variables to components. – Figma docs</p>
</blockquote>
<ul>
<li>For the <a target="_blank" href="https://www.figma.com/widget-docs/working-with-variables/">widget API</a>: This API is connected to the plugin API. It is available to widgets by using the Plugin API the widget contains. </li>
</ul>
<p>Widgets are interactive elements that can be used to create interactive prototypes. Widgets extend the functionality of design files and FigJam boards and are often part of the larger design system, which is a collection of reusable components.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Variables exist in Figma to make your designs better. They are easy to use and create, and are helpful in every design project. In order to save yourself time, make sure to incorporate variables into your design process. </p>
<p>The key is to practice and explore, and you'll get better as you go. </p>
<p>Thank you for reading this article, I hope you enjoyed it! </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Information Architecture? How to Create Userflows and Sitemaps for UX Design ]]>
                </title>
                <description>
                    <![CDATA[ At some point in your design career, you may hear about Information Architecture (or IA). You might even have to create a userflow or sitemap. Now, this article aims to help you go back to the basics and remind you of the meaning and importance of IA... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/information-architecture-userflow-sitemap/</link>
                <guid isPermaLink="false">66d03a33dcbab93f8b58df8f</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ user experience ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ux design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Faith Olohijere ]]>
                </dc:creator>
                <pubDate>Tue, 18 Jul 2023 20:40:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/pexels-sevenstorm-juhaszimrus-425160--1-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>At some point in your design career, you may hear about Information Architecture (or IA). You might even have to create a userflow or sitemap.</p>
<p>Now, this article aims to help you go back to the basics and remind you of the meaning and importance of IA. So if you don't really understand the concept of Information Architecture, this is the best place to be. </p>
<p>We'll also explore how to do a userflow and a sitemap later in the article. Let's get started!</p>
<h2 id="heading-what-is-information-architecture">What is Information Architecture?</h2>
<p>Information Architecture (IA) is the process of planning and designing how information is organized in websites and applications. It focuses on meeting user needs and business goals by creating a logical and user-friendly information structure.</p>
<p>Information Architecture is mostly used by designers to structure the layout of their designs, especially during the sketching/low-fidelity stage.</p>
<h3 id="heading-importance-of-information-architecture">Importance of Information Architecture</h3>
<p>I can't overstate the importance of Information Architecture. Below, I'll share some reasons why every UX Designer should learn what IA means and how to implement it effectively:</p>
<ul>
<li>Organization and Structure: Information Architecture provides a framework for organizing and structuring information. It helps you make sure your designs are logically grouped and categorized.</li>
<li>Content Prioritization and Hierarchy: Hierarchy is one of the basic principles of design, and IA helps you achieve that. It enables designers to highlight key information and arrange content based on its relevance and importance to users.</li>
<li>User-Centric Design: Information Architecture helps designers think of their users during the design process, by considering how users typically think, behave, and search for information. Everyone has mental models, including users, and IA helps to make sure that information is presented in a way that matches the mental models of your already existing/target users.</li>
<li>Navigation: Information Architecture provides a clear way to navigate a design. It allows users to understand intuitively where they are in a site and how to move between different sections of a design.</li>
<li>Business Goals: Information Architecture helps to make sure the information presentation of your design aligns with the goals and objectives of the business/firm/company. </li>
</ul>
<h2 id="heading-types-and-forms-of-information-architecture">Types and Forms of Information Architecture</h2>
<p>There are so many types and forms of Information Architecture, especially since it's used in a lot of fields. But here we'll be looking at Userflows and Sitemaps, which are the most common ones in design.</p>
<h3 id="heading-what-is-a-userflow">What is a Userflow?</h3>
<p>A userflow refers to a diagram that shows the step-by-step journey of a user through a website, application, or system. </p>
<p>Imagine trying to order food online. Some steps you might take include: opening the food ordering application on your phone, signing up/logging in, choosing from the list of available food, choosing how many portions you'd like, and finally making payment online. </p>
<p>That's a typical example of how a user flow might be structured.</p>
<p>Userflows illustrate the paths, interactions, and decision points users encounter as they navigate and complete specific tasks or goals. They help designers and stakeholders understand and optimize the user journey.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/media_127cc680607ff7d6703be50271d9f563fd17e071c.png" alt="Image" width="600" height="400" loading="lazy">
<em>An example of a Userflow</em></p>
<h3 id="heading-what-is-a-sitemap">What is a Sitemap?</h3>
<p>Sitemaps are diagrams that display the layout and organization of content within a website or application. </p>
<p>Imagine a 2 bedroom apartment. The apartment could contain a sitting room, a kitchen, 2 bedrooms, a bathroom, and a dining room. The sitemap simply tells us how we can get to the kitchen from the sitting room/the bedroom/any place in the apartment.</p>
<p>In design, sitemaps provide an overview of the pages, menus, and sub-pages, helping us plan and visualize the information architecture and user experience of the system. They aid in content planning, navigation design, and website development.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/337-sitemap-template.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>An example of a Sitemap</em></p>
<h2 id="heading-differences-between-userflows-and-sitemaps">Differences Between Userflows and Sitemaps</h2>
<ol>
<li>Focus and Perspective: Userflows primarily focus on the step-by-step actions and interactions a user takes within an app or website, to accomplish a task or goal. Sitemaps focus on the overall structure and organisation of a website or an application, depicting the hierarchical relationship between different pages or sections.</li>
<li>Level of Detail: Userflows provide more detailed information about each step of the user's journey, including specific actions, decisions, and possible outcomes at each stage. Sitemaps provide a high-level overview of the app's or website's structure, showing the main pages or sections, without diving into the specific interactions within each page.</li>
<li>User-Centric vs Architectural: Userflows are user-centric and primarily represents the user's perspective and actions within the app or website. Sitemaps are more architectural in nature, representing the overall structure and organisation of an app or a website from a high-level viewpoint.</li>
<li>Interactivity and Decision-points: Userflows highlight interactive elements within the app or website, illustrating the choices and options available to the user at each step. Sitemaps do not explicitly showcase interactivity or decision points. </li>
</ol>
<h2 id="heading-when-to-use-information-architecture">When to Use Information Architecture</h2>
<p>You might be wondering when knowledge about Information Architecture will come in handy. </p>
<p>You can use Information Architecture in any or situation at all, really – like designing a mobile app, a website, a pitch deck, and more. Information Architecture is always helpful because it helps you decide what content/information comes first, what follows and how, and so on. </p>
<p>Typically, you'll think about Information Architecture after conducting user research. This is because research can help you understand the goals and needs of your users, and what they would likely do when they're trying to accomplish a goal on your site. </p>
<p>Also, userflows usually come before sitemaps, because you have to understand how a typical user would journey through your site, before deciding on how the layout or organization of that site would look like.</p>
<h2 id="heading-how-to-create-userflows-and-sitemaps">How to Create Userflows and Sitemaps</h2>
<p>You can use the same methods and tools to create userflows and sitemaps. You just need to understand the differences between them and bear in mind that the purpose of each one is different.</p>
<h3 id="heading-how-to-create-a-userflow">How to Create a Userflow</h3>
<h4 id="heading-step-1-define-your-goals-and-identify-tasks">Step 1: Define your Goals and Identify Tasks</h4>
<p>The first step is to define your goals and objectives for the project, stating what kind of Information Architecture you're trying to create (a userflow or a sitemap). You can just write this down on paper before digitalizing it.</p>
<p>For example: I'm working on a food ordering app, and I'd like to make a userflow showing how a typical user would order food using the app. </p>
<p>I would write down the typical/possible steps the user would have to go through to achieve the task of ordering food. These steps could be:</p>
<ul>
<li>The user opens the application on their phone.</li>
<li>The user signs up or logs into the application.</li>
<li>The user goes to the homepage.</li>
<li>The user chooses from restaurants close to them.</li>
<li>The user selects from the menu and adds food to cart.</li>
<li>The user pays for the food and waits for delivery.</li>
<li>The user exits the application.</li>
</ul>
<h4 id="heading-step-2-choose-a-tool">Step 2: Choose a Tool</h4>
<p>The next step is to choose a tool you want to use to create your userflow. There are lots of tools available for this, like Figjam, Miro, Whimsical, and others. I use Figjam since it's so easy to understand. </p>
<p>Here's what it looks like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Userflow1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Figjam interface</em></p>
<h4 id="heading-step-3-sketch-your-design">Step 3: Sketch your design</h4>
<p>The next thing is for you to sketch your actual flow on Figjam. Before this, you should note that every shape for a userflow has a specified meaning. You can see some shapes, flows and associations, and their meanings below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Userflow2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Shapes, flows, and associations for a userflow.</em></p>
<p>The First Shape (Rounded edge rectangle): This shape represents the start/end of a userflow. It's typically used when you want to start or end a userflow. If you notice, there's also an end tag with a similar shape in the image above. Some people also use a circle to represent this.</p>
<p>The Second Shape (Rhombus): This shape represents a decision. It's used to show when a user has to make a decision like "login", "signup", and so on.</p>
<p>The Third Shape (Rectangle with dotted lines): This represents a group. A group in a userflow can contain process and data, showing that an action has been submitted to the database, and it's expecting feedback from the site.</p>
<p>The Fourth Shape (Parallelogram): This shape shows when the user has to make an input, like "choose how many portions of food they want to order, and so on.</p>
<p>The Fifth Shape (Rectangle with solid lines): This shape shows the process of the user going through the application or website. It might also include screens the user needs to pass through in order to achieve their goal.</p>
<p>The Sixth Shape (Cylinder): this shape represents the data running in the system, which feedback is required from.</p>
<p>Now that you know the different shapes and their uses, you'll need to first draw the shape for 'start':</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Userflow4.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing a Shape</em></p>
<p>Next, you'll want to resize the shape if necessary, and input your text.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Userflow-5.png" alt="Image" width="600" height="400" loading="lazy">
<em>Resizing shape and adding text</em></p>
<p>Up next, you'll need to add another shape and draw a connector. To add a connector, you can either click on the edge of the previous shape and drag, or draw the connector directly from the Figjam tools.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Userflow6.png" alt="Image" width="600" height="400" loading="lazy">
<em>Drawing a connector to the next shape.</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Userflow7.png" alt="Image" width="600" height="400" loading="lazy">
<em>Drawing a Connector from Figjam tools</em></p>
<p>When you do that, you then input your text. (Remember to take note of the meanings/roles of each particular shape).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Userflow8.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You continue this way until you're done adding all the steps in your userflow diagram.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Userflow9.png" alt="Image" width="600" height="400" loading="lazy">
<em>Example userflow diagram with multiple steps</em></p>
<h4 id="heading-step-4-validate-and-finalize">Step 4: Validate and finalize</h4>
<p>Once you're done with your userflow, the next thing is to validate the diagram. This just means reviewing the userflow to make sure it's accurate, usable, and aligns with the users' needs. </p>
<p>Basically just go through the diagram and consider whether it represents the intended user journey, and whether all necessary steps and decision points are included.</p>
<h3 id="heading-how-to-create-a-sitemap">How to Create a Sitemap</h3>
<p>Earlier in the article, I mentioned that the processes for creating a sitemap and a userflow are similar. The difference lies in the purpose of the two diagrams. We'll be exploring how to create a sitemap using Miro, a diagramming tool.</p>
<h4 id="heading-step-1-open-the-tool">Step 1: Open the tool</h4>
<p>The first step obviously, is to open your tool. If you don't have an account already, sign up at <a target="_blank" href="https://www.freecodecamp.org/news/p/d9aa98df-32bc-4463-bf4e-557863ae187c/miro.com">Miro</a> and it should display your dashboard.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Miro Dashboard</em></p>
<p>Next, click on "New Board" to open a blank canvas.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h4 id="heading-step-2-start-drawing-the-sitemap">Step 2: Start drawing the sitemap</h4>
<p>Next, you start drawing your sitemap. You should already know what screens you'll be designing, and how these screens connect to each other. Your userflow might help inform this.</p>
<p>Click on the Shapes tool from the toolbar on the lefthand side of your screen, to bring up all available shapes. </p>
<p>Note that, unlike Userflows where every shape has a meaning, you can use any shape for your sitemaps. Most designers make use of rectangles when doing sitemaps. It's very easy to build and stack, especially when you have lots of pages to represent.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro3.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing a shape</em></p>
<p>A plus icon will appear, and you just have to drag till the shape is to your satisfaction.</p>
<h4 id="heading-step-3-edit-the-shapes">Step 3: edit the shapes</h4>
<p>Next, you edit the shape to add colour, and your text. This could be "Homepage", "Log-in", "Signup", and so on – whatever is the first screen of your design. </p>
<p>When you click on the button, a sub-menu comes up. Here, you can switch your shape type, change text font and size, add text colour, align it, add a border or fill colour for the shape, and more.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro4.png" alt="Image" width="600" height="400" loading="lazy">
<em>Typing inside a shape</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro5.png" alt="Image" width="600" height="400" loading="lazy">
<em>Editing a shape</em></p>
<h4 id="heading-step-4-add-shapes-for-the-next-screens">Step 4: add shapes for the next screens</h4>
<p>Next, you need to draw shapes for the next screens which the homepage branches into. This could be major items on the navigation bar, where you have to click on CTAs (Call To Actions) to open them. </p>
<p>To draw the next shape, you can simply click on the edges of the first one, and the outline of the shape will be displayed.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro6.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sketching the next shape</em></p>
<p>Click on the outline to indicate that you want the shape to stay, and basically edit just like you did the first one.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro7.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro7.5.png" alt="Image" width="600" height="400" loading="lazy">
<em>Editing the second shape</em></p>
<p>Next, you need to add other shapes that represent the subpages which the homepage branches out into. Just click on the first shape like you did when making the first sub-page shape.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro8.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding other sub-pages</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro9.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can also change their colours to differentiate from the homepage and show hierarchy.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro10.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h4 id="heading-step-5-draw-more-pages">Step 5: draw more pages</h4>
<p>Next, you draw shapes for the pages under the first set of sub-pages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro11.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You just continue that way until you're done with your sitemap, and all the screens you want to design have been represented in it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/miro12.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>When you're done making your userflow and sitemaps, you can move on to your low-fidelity wireframes or your main design proper. The IA you've done informs your next step and decides what screens you should be designing in particular.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Information Architecture is very important for you to be able to organize the layouts of your designs and arrange them. This is helpful because it can really help improve the quality of your designs. </p>
<p>There are even templates on some softwares that could help you do your Information Architecture diagrams. Remember to practice as often as you can.</p>
<p>Thank you for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is the 60-30-10 Rule in Design? And How to Use it in Your Projects ]]>
                </title>
                <description>
                    <![CDATA[ As designers, colour is a huge component of our work. But many of us struggle with the usage of colours in our designs.  In this article, you will learn about the 60-30-10 colour rule, how it's used, and see a practical example of it. What is the 60-... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-60-30-10-rule-in-design/</link>
                <guid isPermaLink="false">66d03a38a30d09f91d49b789</guid>
                
                    <category>
                        <![CDATA[ colors ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Faith Olohijere ]]>
                </dc:creator>
                <pubDate>Mon, 15 May 2023 17:20:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/pexels-pixabay-39828.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As designers, colour is a huge component of our work. But many of us struggle with the usage of colours in our designs. </p>
<p>In this article, you will learn about the 60-30-10 colour rule, how it's used, and see a practical example of it.</p>
<h2 id="heading-what-is-the-60-30-10-rule">What is the 60-30-10 rule?</h2>
<p>In the design world, the 60-30-10 rule is a rule that helps to guide designers on choosing and pairing colours for their designs. </p>
<p>To put it simply, this rule says that the dominant/primary colour should take up 60% of your design, the secondary colour should take up 30%, while an accent colour should take up 10% of your design.</p>
<h3 id="heading-why-is-this-rule-so-important">Why is This Rule so Important?</h3>
<ul>
<li>Emphasizing Key Elements: The 60-30-10 rule is great at emphasizing key elements in your design. The dominant colour draws attention to large surfaces and establishes the overall mood of the design. The secondary colour supports it, while the accent colour at 10% highlights specific features or parts of the design. </li>
<li>Visual Balance: To achieve visual balance in a design, one colour/element should not overpower the others. The 60-30-10 rule ensures that there is a sense of equilibrium and balance, by allocating percentages to each colour.</li>
<li>Simplicity and Consistency: Having 3 established colours simplifies the design process. It narrows down your choices and prevents overwhelming combinations of colours.</li>
</ul>
<h2 id="heading-how-to-choose-colours-for-your-designs">How to Choose Colours for Your Designs</h2>
<p>The 60-30-10 rule has three components:</p>
<ul>
<li>The Primary Colour: This is the dominant colour of the design. It forms the foundation of the colour scheme and covers the majority of the design (60%). The primary colour is typically a neutral colour and is often used as the background of the design. Colours like white, blue, beige, and so on can be used as primary colours. </li>
<li>The Secondary Colour: This colour supports the dominant colour and adds more visual interest to the design. It covers about 30% of the design. The secondary colour can be used for typography, icons, and subheadings/subtitles in a design. Colours like teal, black, dark blue, and others can be used as secondary colours.</li>
<li>The Accent Colour: This colour usually covers about 10% of the design. It helps highlights specific sections of the design like buttons, call-to-action elements, or any element that needs emphasis in a design. Accent colours are usually colours that have high contrast. Colours like yellow, orange, light green, and others make good accent colours.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/60-final.png" alt="Image" width="600" height="400" loading="lazy">
<em>Illustration of the 60-30-10 rule</em></p>
<p>It's important to choose colours that complement each other for your designs. This will contribute to the overall aesthetics and create a dynamic and engaging visual experience. </p>
<p>If you are worried about what colours to use while designing, you can always check out free colour palette generators. Some colour palette generators you try out include:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/p/251c1c45-6222-4618-ae62-23843967d9bd/coolors.co">Coolors.co</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/p/251c1c45-6222-4618-ae62-23843967d9bd/mycolor.space">Color Space</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/p/251c1c45-6222-4618-ae62-23843967d9bd/color.adobe.com">Adobe Color</a></li>
</ul>
<h2 id="heading-example-hero-page-using-the-60-30-10-rule">Example Hero Page Using the 60-30-10 Rule</h2>
<p>I designed an hero page to give an illustration of how the rule works.</p>
<h3 id="heading-step-1-choosing-a-frame">Step 1- Choosing a Frame</h3>
<p>I had to choose what desktop frame I wanted to use for the hero page. I chose Macbook Air.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Landing-Page1-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Macbook Air Desktop frame</em></p>
<h3 id="heading-step-2-adding-a-grid">Step 2- Adding a Grid</h3>
<p>Next, I added a grid to the frame. I used these specifications: Columns-12, Margin-100.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Landing-Page2-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding the Grid</em></p>
<h3 id="heading-step-3-adding-content">Step 3- Adding Content</h3>
<p>Next up, I added the logo and the navigation bar.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Landing-Page3-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding the logo and nav bar</em></p>
<p>I already knew how I wanted the structure of my hero page to look like, so I just added the rest of my design content.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Group-2--5-.png" alt="Image" width="600" height="400" loading="lazy">
<em>My Completed Hero Page Illustrating the 60-30-10 Rule.</em></p>
<p>For the design above:</p>
<ul>
<li>My primary colour is white. It covers the background of the design. It enhances readability and legibility of other elements in the design. Also, I chose white because it's a neutral colour, as I mentioned earlier.</li>
<li>My secondary colour is a saturated black. It supports the primary colour, and is used for text and typography.</li>
<li>My accent colour is a shade of brown. It adds some pop, and provides some contrast in the design.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The 60-30-10 rule is used in different design sectors because of how useful it is to designers. Also, it is not a strict requirement and can be adjusted to suit individual preferences and design goals. </p>
<p>By following the 60-30-10 rule, you can achieve a well-balanced color scheme that ensures visual interest and coherence in your design. Basically, just choose: </p>
<ul>
<li>Your primary colour – a neutral colour, </li>
<li>Your secondary colour – a colour that supports the primary colour, and </li>
<li>Your accent colour – a colour that pops! </li>
</ul>
<p>Whatever colours you decide to use for your design depend on the design objectives and the overall aesthetic you want to achieve. Remember that mastery of colours come with adequate practice. So make sure to practice more and you will see a lot of improvement in your usage of colours.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Wireframing? How to Go from Paper Sketches to High Fidelity Wireframes ]]>
                </title>
                <description>
                    <![CDATA[ What are Wireframes? Wireframes are visual representations of the structure, layout, and functionality of a website, application, or other digital product.  You typically create them during the early stages of the design process, and they provide a s... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-wireframing/</link>
                <guid isPermaLink="false">66d03a3f64be048ac359a361</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #wireframe ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Faith Olohijere ]]>
                </dc:creator>
                <pubDate>Tue, 09 May 2023 22:06:49 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/unsplash_Pa0I38PfNPs.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="heading-what-are-wireframes">What are Wireframes?</h2>
<p>Wireframes are visual representations of the structure, layout, and functionality of a website, application, or other digital product. </p>
<p>You typically create them during the early stages of the design process, and they provide a simplified and focused view of the user interface and user experience.</p>
<p>You can create a wireframe using a variety of tools, including paper and pencil, whiteboards, or specialized digital software. They usually consist of basic shapes, lines, and text, and aim to communicate the hierarchy of information, the placement of interactive elements, and the flow of user interactions.</p>
<p>Wireframes serve as a blueprint for the design process. They allow designers and stakeholders to quickly iterate and refine ideas before investing time and resources into creating a fully functional prototype or final product. They are an essential tool for creating effective and user-friendly digital experiences.</p>
<h2 id="heading-why-is-wireframing-important">Why is Wireframing Important?</h2>
<p>Wireframing is an important process in web and app design because it helps designers to plan and communicate the layout and functionality of a website or application before it is built. Here are some reasons why wireframing is important:</p>
<ol>
<li>Wireframing helps stake holders visualize the structure of the design: Wireframing allows designers to create a visual representation of the website or application's structure. This includes the layout of pages, navigation, and the placement of various elements.</li>
<li>It helps designers focus on functionality: With wireframing, designers can focus on the functionality of the website or application without getting distracted by colors, typography, and other design elements.</li>
<li>It saves time and money: Wireframing can save time and money in the long run by identifying potential problems and making necessary changes early on in the design process, rather than during the development phase.</li>
<li>It's an easy way to gather feedback: Wireframes are a great way to gather feedback from stakeholders and users, as they provide a clear and simple representation of the design without distracting visual elements.</li>
<li>Plan for responsive design: Wireframing is essential when designing for different screen sizes and devices. It allows designers to plan for responsive design and ensure that the website or application works well on all devices.</li>
</ol>
<h2 id="heading-types-of-wireframes">Types of Wireframes</h2>
<p>Everyone has a specific way of doing wireframes. Some designers go from paper sketches to high fidelity wireframes or from low-fidelity wireframes to high-fidelity wireframes. </p>
<p>It all depends on the particular project the designer is working on, what they intend to achieve, and the timeframe they have.</p>
<h3 id="heading-paper-sketches">Paper Sketches</h3>
<p>I begin my wireframing process by doing paper sketches first, because it allows me put out my ideas really fast without having to bother about neatness and quality. It also saves time when designing – you just think of quick solutions and put them on paper.</p>
<h4 id="heading-some-techniques-for-paper-sketching">Some Techniques for Paper Sketching</h4>
<ul>
<li><strong>Crazy Eights</strong></li>
</ul>
<p>In the design world, "Crazy Eights" is a quick sketching exercise that helps designers to quickly generate a variety of design ideas and explore different solutions to a problem, in a short amount of time. </p>
<p>Here's how to do Crazy Eights in design:</p>
<ol>
<li>Start with a blank sheet of paper and fold it in half, then in half again, and one more time so that you end up with 8 rectangles on the page.</li>
<li>Set a timer for 8 minutes.</li>
<li>Within the first rectangle, sketch out an idea for the design problem you're working on. It doesn't need to be perfect, just get the basic idea down on paper.</li>
<li>When the timer goes off, move on to the next rectangle and sketch a new idea. Keep going until you've filled all 8 rectangles.</li>
<li>Once you've completed all 8 sketches, take a few minutes to review your ideas and identify the strongest ones.</li>
<li>Use the strongest ideas as a starting point for your design, and continue refining and iterating until you have a final product.</li>
</ol>
<p>You'll see an example of this in a bit when I walk you through my wireframing process.</p>
<ul>
<li><strong>20 Second Sketches</strong></li>
</ul>
<p>Set a timer for 20 seconds and sketch a simple object or scene. Repeat this exercise multiple times, trying to capture as much detail as possible in each sketch.</p>
<ul>
<li><strong>Collaborative Sketching</strong></li>
</ul>
<p>Pair up with another person and take turns adding to a sketch. Each person has a set amount of time to add their own unique element to the drawing. This exercise encourages collaboration and improvisation.</p>
<h3 id="heading-low-fidelity-wireframing">Low-Fidelity Wireframing</h3>
<p>Low-fidelity wireframing is a technique of creating a rough visual representation of a design using simple shapes, lines, and text. Low-fidelity wireframes are the most basic of wireframes. This type of wireframing is typically done with pen and paper, or with a digital tool that allows for quick, low-detail sketches. </p>
<p>Mostly, they focus on the core content and structure of the interface, and are simple and straightforward. Low-fidelity wireframes are a useful tool for designers to quickly explore and iterate on different layout and content options, without getting bogged down in details that can distract from the overall design direction. </p>
<h4 id="heading-advantages-of-low-fidelity-wireframing">Advantages of Low Fidelity Wireframing</h4>
<ul>
<li>Speed: Low-fidelity wireframes can be created quickly and easily, allowing designers to explore multiple ideas in a short amount of time.</li>
<li>Flexibility: Low-fidelity wireframes are easy to modify and change as the design evolves, allowing designers to iterate quickly.</li>
<li>Focus: By focusing on the structure and layout of a design, low-fidelity wireframing helps designers avoid getting distracted by details that may not be relevant.</li>
<li>Collaboration: Low-fidelity wireframes can be easily shared and discussed with other team members, allowing for greater collaboration and feedback.</li>
</ul>
<h4 id="heading-disadvantages-of-low-fidelity-wireframing">Disadvantages of Low Fidelity Wireframing</h4>
<ul>
<li>Lack of Detail: Low-fidelity wireframes may not provide enough detail to fully convey the intended design, which can lead to misunderstandings and miscommunications.</li>
<li>Limited Interactivity: Low-fidelity wireframes are static and do not allow for interaction, which can make it difficult to test usability and user flow.</li>
<li>Limited Realism: Unlike high fidelity wireframes, low-fidelity wireframes may not accurately represent the final product, which can make it difficult to communicate the design to stakeholders who may not be familiar with wireframes.</li>
</ul>
<h4 id="heading-why-you-might-want-to-use-low-fidelity-wireframes">Why You Might Want to Use Low-Fidelity Wireframes</h4>
<ul>
<li>For early-stage conceptualization: Low-fidelity wireframes are great for early-stage conceptualization. Because they allow you to quickly iterate and experiment with different layout options without getting caught up in the visual details, low-fidelity wireframes are extremely useful during the initial stages of your design. </li>
<li>For Time and Resource Efficiency: In situations where time is of great essence, low-fidelity wireframes helps to make changes more rapidly, saving time when needed. Also, it requires fewer resources, which is ideal for situations where resources are scarce.</li>
<li>For User Testing and Feedback: Low-fidelity wireframes provide a clear representation of the overall structure of your design, allowing for easier feedback from stakeholders and team members. Low-fidelity wireframes are also important during user testing sessions, as it helps you collect valuable insights on the fundamental structure and functionality of a design, before investing significant effort in visual design. </li>
</ul>
<h3 id="heading-mid-fidelity-wireframing">Mid-Fidelity Wireframing</h3>
<p>Mid-fidelity wireframing refers to wireframes that are created with a moderate level of detail and design elements. These wireframes typically focus on the overall structure of a product and may include basic typography and design elements.</p>
<h4 id="heading-advantages-of-mid-fidelity-wireframing">Advantages of Mid-Fidelity Wireframing</h4>
<ul>
<li>Efficient Design Process: Mid-fidelity wireframing can be completed quickly and efficiently, allowing designers to iterate and test their designs faster.</li>
<li>Cost-effective: Mid-fidelity wireframes are less expensive to create than high fidelity wireframes, making them a more cost-effective option for design projects.</li>
<li>Usability Testing: Mid-fidelity wireframes can be used for usability testing, providing insights into user behaviour and interaction with the product.</li>
<li>Flexibility: Definitely one of the most importnat advantages of mid-fidelity wireframes. Mid-fidelity wireframes are less detailed than high fidelity wireframes, making it easier to make changes and pivot design direction during the design process.</li>
</ul>
<h4 id="heading-disadvantages-of-mid-fidelity-wireframing">Disadvantages of Mid-Fidelity Wireframing</h4>
<ul>
<li>Less Realistic: Mid-fidelity wireframes may not accurately represent the design's final look, which can impact stakeholder and client expectations.</li>
<li>Limited Visual Details: Mid-fidelity wireframes do not provide as much detail as high fidelity wireframes, making it difficult to communicate the final design vision to stakeholders.</li>
<li>User Experience Limitations: Because mid-fidelity designs do not have enough visual details to test the user experience effectively, leading to potential usability issues.</li>
</ul>
<p>You'll see an example of this below when we walk through my process.</p>
<h4 id="heading-why-you-might-want-to-use-mid-fidelity-wireframes">Why You Might Want to Use Mid-Fidelity Wireframes</h4>
<ul>
<li>For Refining Structure and Content: When you need to refine the structure, content and layout of your design, mid-fidelity wireframes are beneficial. They allow you add more detail to your wireframes while being relatively quick to create and modify.</li>
<li>Information Architecture: Mid-fidelity wireframes provide a clearer structure and visual representation of the design, showing off the userflow better than low-fidelity wireframes. </li>
<li>Stakeholder Presentation and Approvals: Mid-fidelity wireframes are more polished and appealing than low-fidelity wireframes. This makes them a more effective tool when presenting design ideas to stakeholders and clients.</li>
<li>Design Consistency: By adding more visual details to the wireframes, a consisent design language can be established across multiple screens or pages.  </li>
</ul>
<h3 id="heading-high-fidelity-wireframing">High-Fidelity Wireframing</h3>
<p>High fidelity wireframing refers to the creation of detailed, visually-rich wireframes that closely resemble the final product or website. </p>
<p>These wireframes are often created using tools like Adobe XD or Figma and include elements like typography, color schemes, and detailed user interface elements.</p>
<h4 id="heading-advantages-of-high-fidelity-wireframing">Advantages of High-Fidelity Wireframing</h4>
<p>Some advantages of high-fidelity wireframes include:</p>
<ul>
<li>Detailed Representation: High fidelity wireframes provide a more detailed representation of the final product, making it easier to communicate the design vision to stakeholders.</li>
<li>Efficient Testing: High fidelity wireframes can be used for testing purposes, helping designers identify any usability issues before the development phase begins.</li>
<li>Better Visuals and User Experience: High fidelity wireframes are aesthetically pleasing and provide a more realistic view of the final product which helps users visualize the design better. It gives the users better understanding of how to interact with the product.</li>
</ul>
<h4 id="heading-disadvantages-of-high-fidelity-wireframing">Disadvantages of High-Fidelity Wireframing</h4>
<ul>
<li>Time-consuming: High fidelity wireframes take longer to create than low-fidelity wireframes. It can be challenging to complete high fidelity wireframes withing tight project timelines. </li>
<li>Cost: High fidelity wireframes can be expensive to create, as it requires a significant amount of skill and effort from the design team.</li>
<li>Limited Flexibility: High fidelity wireframes are not as flexible as low-fidelity or mid-fidelity wireframes. They are detailed and specific, which makes it challenging to change the design direction once they are completed.</li>
</ul>
<p>You'll see an example of this in a moment during my process walkthrough.</p>
<h4 id="heading-why-you-might-want-to-use-high-fidelity-wireframes">Why You Might Want to Use High-Fidelity Wireframes</h4>
<ul>
<li>Hand-off to Development: High-fidelity wireframes provide accurate visuals, detailed specifications, and design assets that facilitate the handoff process to developers. </li>
<li>High Visual Realism: High-fidelity wireframes closely resemble the final visual design and provides a realistic representation of the user interface, to potential users and stakeholders.</li>
<li>User Experience Validation: High-fidelity wireframes allow you to test and validate the user experience more accurately. With realistic visuals, you can simulate user interactions, flows and transitions, enabling users to provide meaningful feedback and uncover potential usability issues before development.</li>
<li>Design Consistency: By including more visual elements than the mid-fidelity wireframes, high-fidelity wireframes helps establish a consistent visual hierarchy and design language that can be carried over to the final product.</li>
<li>Style Guide Creation: High-fidelity wireframes play a crucial role in developing a style guide for your design. They establish the visuals and design assets that will be used till the launch of the product. </li>
</ul>
<h2 id="heading-my-wireframing-process">My Wireframing Process</h2>
<p>I worked on a mobile app to help pregnant mothers through their pregnancy journey. I started with paper sketches, moved on to mid fidelity wireframes, and then did my high fidelity wireframes. </p>
<h3 id="heading-step-1-paper-sketches">Step 1 – Paper Sketches</h3>
<p>For my paper sketches, I used the Crazy Eights(8s) method, which is a very quick way to put out ideas and inspirations. </p>
<p>Basically, I took out my drawing book, drew 8 identical phone frames and sketched out how I wanted my design to look using a pen. The sketches were more elaborate than usual, because I wanted to move straight to doing mid-fidelity wireframes.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/IMG_20230507_092729_458.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Crazy Eights sketches</em></p>
<h3 id="heading-step-2-moving-to-mid-fidelity-wireframes">Step 2 – Moving to Mid Fidelity Wireframes</h3>
<p>Next up, I opened a new Figma file on my laptop and transferred my sketches on paper to phone mockups on Figma. </p>
<p>First, I chose the frame I wanted to use for the designs – Iphone 13 pro.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Phone-frame1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choose the phone you want to use</em></p>
<p>Then I used my sketches as a guide. It was mostly replicating what I already had on paper, digitally.</p>
<p>Next I used rectangles to denote images, and lorem ipsum (dummy text) for parts of the design which needed long texts.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/frame-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding rectangles and dummy text</em></p>
<p>Prior to this, I had created a style guide. So I just got the icons from the style guide.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Group-10.png" alt="Image" width="600" height="400" loading="lazy">
<em>My Mid-fidelity Wireframes</em></p>
<h3 id="heading-step-3-creating-high-fidelity-wireframes">Step 3 – Creating High Fidelity Wireframes</h3>
<p>This was the last phase of my wireframing. Here, I added colours, images, and real text to my designs.</p>
<ol>
<li>I started by adding colours to the mid-fidelity screens.</li>
<li>I also wrote out real text for the screens, making sure the copy matched the branding and purpose of the app.</li>
<li>Lastly, I added illustrations and images where needed, helping users relate to the design.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/frame-1-high-fidelity.png" alt="Image" width="600" height="400" loading="lazy">
<em>Example of high fidelity wireframing</em></p>
<p>In high-fidelity wireframing, once the overall structure is in place, you can start adding more details and refining the design. This includes adding visual elements such as images, icons, and typography, as well as defining interactions and transitions.</p>
<p>Share the high-fidelity wireframe with stakeholders, users, or other team members, and gather feedback. Use this feedback to refine the design and make any necessary changes. </p>
<p>Once the wireframe has been approved and refined, finalize it by adding annotations, notes, and any other necessary documentation. The wireframe should be detailed enough to provide a clear understanding of the design to developers, but not so detailed that it hinders the design process.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Group-9.png" alt="Image" width="600" height="400" loading="lazy">
<em>Completed High Fidelity Wireframes</em></p>
<p>Note that you can use any type of wireframe you would like to, depending on the specific project you're working on, the stage of the project and your objectives. You should also consider the complexity of the design, the available time and resources, and the needs of the stakeholders and users when determining the appropriate fidelity level for your wireframes. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Wireframing is an essential step in the design process that helps ensure a successful outcome. It enables designers to visualize the layout and functionality of a platform before investing significant time and resources into coding and development. </p>
<p>Incorporating wireframing into your design process can lead to more efficient, effective, and user-friendly designs.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Market a New Project –Incorporate Design, Create a Landing Page, and Get Customers ]]>
                </title>
                <description>
                    <![CDATA[ By Jane Sorensen Only a few of us come naturally to self-marketing. Most of us prefer making the thing and enjoy showing it off (at least a little!), but hope it’ll be appreciated on its own merits – or that someone else will champion it.  Deliberate... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-market-your-new-project-incorporate-design-create-a-landing-page-and-get-your-users-97812fd9dd4d/</link>
                <guid isPermaLink="false">66d45f32264384a65d5a9532</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ marketing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 03 Mar 2023 18:50:00 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*RlD_EebvaZt--pxPDmc0rQ.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Jane Sorensen</p>
<p>Only a few of us come naturally to self-marketing. Most of us prefer making the thing and enjoy showing it off (at least a little!), but hope it’ll be appreciated on its own merits – or that someone else will champion it. </p>
<p>Deliberate marketing and sales makes people uncomfortable, and understandably so, because asking for money is like asking for love.</p>
<p>But if you worked hard on something thoughtful, it deserves to be noticed! And that means you’ll have to market it.</p>
<p>I spent years resisting marketing. Self-promotion is vulgar and sales seemed unseemly. And so I learned the hard way:</p>
<ol>
<li>Your friends and colleagues aren’t a channel (a conduit to the people who want your goods). They might not even have your customers as part of their network or audience. You can ask, but don’t rely on the people you know. Go find the people you want to help!</li>
<li>If no one knows about your service or product, you don’t have a business, you have a hobby. So start marketing, and if you can’t find sales, it’s still a hobby, but at least you’ll be aware of its potential.</li>
<li>The things that annoy you about others, or fear doing yourself, are probably things you should learn how to do. Just do them in a way that wouldn’t annoy you if you were a customer.</li>
</ol>
<p>I’ve written this to break down what I learned-while-doing about creating a product or service for people. Specifically, it’s about the landing pages and channels you’ll use to promote your product or service, and the basics of having an email list. </p>
<p>Here’s what we'll cover:</p>
<ol>
<li><a class="post-section-overview" href="#heading-how-to-design-to-serve-real-people-not-just-your-creativity">How to Design to Serve Real People (Not Just Your Creativity)</a></li>
<li><a class="post-section-overview" href="#heading-how-to-communicate-what-youre-offering-while-you-develop-it">How to Communicate What You’re Offering While You Develop it</a></li>
<li><a class="post-section-overview" href="#heading-why-email-marketing-is-necessary">Why Email Marketing is Necessary</a></li>
<li><a class="post-section-overview" href="#heading-how-to-integrate-the-mailing-list-with-your-website">How to Integrate a Mailing List with Your Website</a></li>
<li><a class="post-section-overview" href="#heading-what-landing-pages-are-about">What Landing Pages Are About</a></li>
<li><a class="post-section-overview" href="#heading-writing-rewriting-and-sharing-your-content">Writing, Rewriting, and Sharing Your Content</a></li>
<li><a class="post-section-overview" href="#heading-different-landing-pages-and-their-analytics">Different Landing Pages and Their Analytics</a></li>
<li><a class="post-section-overview" href="#heading-how-to-avoid-the-free-ick-factor">How to Avoid the Free = Ick Factor</a></li>
<li><a class="post-section-overview" href="#heading-multiple-offerings-and-list-groups">Multiple Offerings and List Groups</a></li>
<li><a class="post-section-overview" href="#heading-final-advice-for-beta-testers-and-the-video-intro">Final Advice for Beta Testers, and the Video Intro</a></li>
<li><a class="post-section-overview" href="#heading-in-conclusion">Conclusion</a></li>
</ol>
<h2 id="heading-how-to-design-to-serve-real-people-not-just-your-creativity">How to Design to Serve Real People (Not Just Your Creativity)</h2>
<p>You are likely working on an idea based on a need you identified and a thing you are able to do. Now you’re trying to make it fit for other people. That’s one way to approach design, and that’s okay. Design is about elegantly fulfilling a need:</p>
<ol>
<li>The customer is experiencing <strong>pain</strong> in getting from state A to A’ or B : an obstruction or a gap that they are having trouble negotiating.</li>
<li>The customer is getting around the obstruction or gap in a habitual or work-around kind of a way, but there’s <strong>frustration</strong>: inefficiency, extra steps, aesthetics, approvals. (There could be a whole other way of doing things, but they don’t know it yet.) And lastly (or alternatively):</li>
<li>The customer is seeking an <strong>emotional reward</strong> like security, status, identity, love, beauty, harmony, health, self-expression, self-actualization, or the attainment of a dream.</li>
</ol>
<p>Figure out what you’re trying to respond to with your idea. (If it’s item #3, tread carefully. Purveyors in this category are consumer brands, artists, and charlatans. If this was the category <em>you</em> fell into when being marketed to, you wouldn’t want to be duped!) </p>
<p>Before you do anything else, you have to do the hard part: <strong>go out and ask people non-leading questions about the problem.</strong> Don’t propose your solution in any way; <em>listen</em> for what they say would be their solution. </p>
<p>If you get out of your own head and listen to what’s in other people’s heads, you’ll come up with some a-ha moments that will help you in two ways:</p>
<ol>
<li>You can design your product or service to better respond to their actual needs, or</li>
<li>You can communicate to this exact need and demonstrate how your product will help them.</li>
</ol>
<p>The research you’re doing for the design and the communication is your value proposition. The features you build will correspond to your value proposition, and it will all evolve accordingly.</p>
<h2 id="heading-how-to-communicate-what-youre-offering-while-you-develop-it">How to Communicate What You’re Offering While You Develop It</h2>
<p>Too many people wait until a product is well underway before they start talking about it. Why?</p>
<p>There are a lot of reasons, many of which stem from “impression management” that range from seeming boring (your idea is a knock-off) or flaky (it changes all the time), to inducing the kind of envy that courts competition and controversy. </p>
<p>People implicitly know both the need and the catch-22 of building “social proof.” But know this: the world will be utterly indifferent to your ideas until you have an audience! </p>
<p>There are many ways—channels—to reach your customers, and only some of them are online. </p>
<p>As explained in <a target="_blank" href="https://www.goodreads.com/book/show/22091581-traction">Traction</a>, you need to start developing and communicating with your marketing channels at the same time as you develop the product. You may even need to add or shut down a channel to find and focus on your customers. </p>
<p>If all goes well, by the time your product is ready, your audience will be, too.</p>
<p>So one of the necessary parts of those channels—for almost all of them, and certainly when it comes to a code-based product—are landing pages and the email list.</p>
<h2 id="heading-why-email-marketing-is-necessary">Why Email Marketing is Necessary</h2>
<p>If you already engage with the folks in your topic area on social media, then you’ve got an opportunity to shine. But places you hang out on also have a culture, and through this, you’re at risk of being distracted or seduced and misdirected. </p>
<p><strong>Your attention is precious, and you should use social media only to glean and boost what’s worthy of it.</strong> If social media is costing you time, focus, equanimity, or social capital (status is a zero-sum game!), then it’s working against you.</p>
<p>Which brings us down to email. Even with the rise of Slack and Microsoft Teams, email is how we get work done and find out about things in our communities. </p>
<p>In all honesty, the high-frequency repeat demand of email is not enjoyable, and you have to be aggressive with how you keep your Inbox working for you. </p>
<p>Most of us subscribe to too many newsletters, and too many email marketers have been abusive of our attention. The sheer volume buries good email habits, along with what’s actually needed in your inbox, because who can keep up? And then we rely on extensions and AI to substitute for a reasonable attention-load.</p>
<p>Yet despite all that, there are emails that I love getting (though I wish just a little less frequently). When I sit down to read my Inbox or folders, I share the articles I like, regardless of their date.</p>
<p>Email is private communication. Barring any forwards, bcc:, or abuse of privacy (which you shouldn’t expect from recipients of a broadcast list), it’s simply a message from the list owner to you, or you to your list members. Readers can ignore it, engage with it, or simply read and archive it. </p>
<p>Unlike other channels, where you don’t know who’s-seen-what unless they engage with it, you own this connection to your audience. It can’t be reduced or taken away by the social platform; you only lose them if their emails bounce or they unsubscribe. </p>
<p>Email isn’t subject to the algorithms that bump you up or down in visibility and priority, depending on engagement. </p>
<p>It’s also not subject to the dampening influence of observers who pay attention to the online behaviour of their connections. We all want group interactions to go in our favour, so people are careful what bandwagons they join.</p>
<p>Email, being private, doesn’t have these meta-filters, so it’s a way to get to know your customer, while letting them get to know you. How refreshingly old-fashioned and well-behaved! </p>
<p>And the truth remains: if people let into your email box, and you <strong>make yourself a good guest</strong>, you’re welcome to continue to talk about your mutual interests. Your audience will come to like, respect, share, and buy from you.</p>
<p>So before you start communicating with people on your list, decide how you’re going to make yourself a good guest.</p>
<h3 id="heading-best-practices-for-an-email-list">Best practices for an email list</h3>
<p>First, email hygiene:</p>
<ol>
<li>Their inbox isn’t free real estate for advertising. Always provide information of value that they don’t have to click for.</li>
<li>Their priorities in life aren’t yours. Do not abuse them with frequency or urgency. Set a schedule of quarterly or every six weeks (ideal for charities; startups, too), monthly (professional events and news round-ups), or bi-weekly or weekly (for local events or lots of relevant news). More than once a week? That’s pestering.</li>
<li>Tell them when to expect you: either a consistent date (e.g. the 14th; the second Thursday of the month; Wednesday afternoons), or an anticipation of when the next newsletter will be.</li>
<li>Do not resend-to-unopened. So what if people aren’t opening your email? It might be because they’re backlogged or doing other things. You resending it (even with a different subject line, such as A/B testing) <strong>double-taxes their attention</strong>. They don’t need it. Don’t use this self-serving email tool (your provider will suggest you try it!). If it’s really that important, <em>you</em> take the hit and write them a new message. </li>
</ol>
<p>Next, style and personality (yes, including for projects and brands):</p>
<ol>
<li>Create a <strong>simple</strong>, consistent, and personalized (to them by name, not “hey, everybody!”) template to make your efforts easier and your message readable.</li>
<li>Give readers a reason to open it (a good headline and lede every time!). Write from a point of view. You want them to enjoy your message, or at least understand why it’s pertinent.</li>
<li>People respect it when your message is complete and not trying to get something out of them. If you tease them a little—curiosity gets clicks—this is doubly important. Do you need that click (for your advertising model)? Or is it FYI?</li>
<li>Is the click where the value lies for them? Then be succinct, but not too brief. Give them more than a headline and an image. Give them enough that will jog their memory after they have clicked through. If it’s that good, they’ll look for it again in their archive.</li>
<li>Don’t make an image in an email clickable, unless it’s to zoom the image! Accidental clicks are sneaky and annoying. <strong>Make every click obvious and intentional</strong>.</li>
<li>Even if your company is big, monitor the email address you send from. Let people get in touch with you! When I encounter a “noreply—go to knowledgebase/tech support,” I feel like they don’t have much concern for how their output impacts me or my input impacts them.</li>
</ol>
<h2 id="heading-how-to-integrate-the-mailing-list-with-your-website">How to Integrate the Mailing List with Your Website</h2>
<p>How? Easy. Email marketing service providers give you an API key and a plugin for your website. (These aren’t shown on the accompanying video, so I’m bridging this very small gap.)</p>
<p>If you haven’t already, sign up for MailChimp (or ConvertKit, Blackbaud, Ontraport, MadMimi, ConstantContact, AWeber, or others). Then download and install the corresponding plugin, such as this one here (I’m using MailChimp and WordPress). Find your API key, and enter it in the plugin. These are (typically) the only two screens you need. </p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*8zqUmiS8ej1JWT466vqq4g.png" alt="Screenshot of WordPress configuration settings for Mailchimp" width="800" height="448" loading="lazy">
<em>The Mailchimp plugin to integrate with WordPress and WooCommerce.</em></p>
<ul>
<li>Alternatively, the “Mailchimp for WP” plugin will do the same with your API key, and it helps you make prettier forms for your website. It also lets you update them globally (across all pages) that use its shortcode. I talk about this later, and you‘ll see it in action in the accompanying video.</li>
<li>Plugins are not only for subscribing! They can also help you get information about what page induced someone to sign up, and sort them into groups. Your email provider will have documentation about that.</li>
</ul>
<p><strong>This article isn’t going to discuss pop-ups, slide-ins, or lightbox (modal) email opt-ins.</strong> The learning curve for implementing them isn’t fast or easy. Swearing will be involved, and possibly some tears. When it’s time for you to make a pop-up, dedicate time and money for learning, creation, and <strong>repeated</strong> testing. </p>
<p>Once you’ve connected your website to your email service provider, it’s time to build a landing page.</p>
<h2 id="heading-what-landing-pages-are-about">What Landing Pages Are About</h2>
<p>A landing page is a webpage that informs the reader of your offering and obliges them to do one thing: download your app, subscribe to your email list, register their interest in your course, event, book, product, or other development. </p>
<p>The landing page is about removing as much friction as possible between the customer and <em>their goal, by your means</em>. It contextualizes their pain, their frustration, or their desire, and how you’re solving it for them. </p>
<p>People’s patience, interest, and attention spans are short. Get out of their way. It’s the “main focus, explain, Call to Action.” Landing pages are going to be very useful to you, because they gauge people’s interest in at least committing the time to know more. </p>
<p>Be clear about your idea, about what you’re doing, its benefits, and what to expect of email from you. Strip out any extraneous stuff—your social links or any other menu navigation. <strong>When you give people a path out of the action you want them to take, even “more information,” they take it, and almost never commit (convert).</strong> </p>
<p>If they’re determined to know more, they’ll truncate your URL back to your domain and poke around, which is why some marketers buy a unique domain for every product or campaign. With this in mind, I resisted putting any navigation on my WordPress site until I had to have it, and then I put it at the bottom of the page.</p>
<p>So let’s build it:</p>
<ul>
<li>Write out your offering—your value proposition—in 250 words or less (see below for writing tips).</li>
<li>Pull five of those sentences—the most powerful, clear ones that can make a semblance of a complete argument—and use those in your landing page. (You can use more than 5 sentences, just, those are the anchors.)</li>
<li>Place one call-to-action (CTA)—generally, Sign Up to the email list (“waitlist” until you have something to announce)—within the first screen of the landing page (see <em><a class="post-section-overview" href="#OptIn">“Opt-in form submission how-to,</a>”</em> below).</li>
<li>Then, use an explainer video, an image, and other persuasive writing such as storytelling and testimonial quotes. These ensure that the reader understands the use case and how it can help them.</li>
<li>Provide a final CTA with the opt-in form, and make it central, obvious, and compelling. In one talk I attended on this topic, they mentioned having a cartoon or an image of a person looking directly at the CTA, and how well it “converted” people.</li>
</ul>
<p>Conversion simply means people believe your copy enough to want to provide something of value—that is, their email address—in exchange for learning or obtaining more. </p>
<p>To take advantage of the chance that someone searches for your value proposition, use SEO keywords in the landing page. Use a three-word phrase in the page’s keyword meta data, based on the seeker's likely search term for their need. This is often the most similar idea out there. Use a short URL that matches your headline and a keyword.</p>
<p>Don’t worry about how your page compares to slick landing pages from bigger companies. They can afford an agency or a landing page provider. </p>
<p>Once you’ve learned how to do this the from-scratch way, you’ll better evaluate the many landing page solutions that’ll do the same for you. MailChimp even provides unique campaign landing pages on your account. (This is covered in the accompanying video.)</p>
<h2 id="heading-writing-rewriting-and-sharing-your-content">Writing, Rewriting, and Sharing Your Content</h2>
<p>Here are a few tips that will make any writing better:</p>
<ul>
<li>Get out of your own way and just dump it. Tell it like you would to someone you know. If you’ve met someone like your ideal customer in real life, write to that person.</li>
<li>If your project has you <em>and</em> someone else working on it, say <em>we</em>. If it’s just you, say <em>I, unless</em> it’s a statement that empathizes and identifies with the customer’s situation. <strong>Honesty disarms and connects.</strong></li>
<li>Make long sentences short. (Then, decide if you need that sentence after all.)</li>
<li>Chop long paragraphs into two or three short paragraphs, but <strong>do not chop paragraphs into single sentences unless it makes sense in the context of what you're writing</strong>. </li>
<li>Paste it into the <a target="_blank" href="http://www.hemingwayapp.com/">Hemingway app</a> and make sure that it’s no higher than Grade 9. Grade 6 is even better.</li>
<li>Read it aloud. Does it sound like you? How about like <a target="_blank" href="https://www.momtestbook.com">talking to your mom</a>? Fix it ‘til it does.</li>
<li>Make a <strong>headline</strong> for the landing page—<strong>and a matching social media lede, and email subject line</strong>—that is clear, curious, and bold. <em>This is super-important.</em> Try to write ten different headlines. Read up on headline writing; it will <strong>always</strong> inspire you to come up with phrases you’d never think up on your own. If you write a bunch, you’ll find a great one.</li>
<li>Show your page to someone else.*</li>
<li>The next day: one final check, and then publish it.</li>
<li><p>If you need to edit it again later, that’s to be expected. The days of frozen content are long gone.</p>
</li>
<li><p>If someone uses the word “confusing” about your writing (usually with a gravity that judges <em>you</em>), don’t take it personally. Ditto for any other critical comment that deflates you when you’re putting a lot of heart and anxiety into it. (You should be writing from the heart, and anxiety, properly understood, keeps you sharp.) </p>
</li>
</ul>
<p>You just need to tighten up your writing and layout. You could also be hearing from someone who isn’t part of your audience, and there are a lot of people who won’t understand what isn’t written exactly for them. </p>
<p>Take the useful feedback and make a change. </p>
<p><strong>Tailor the message for each type of share you do,</strong> and be savvy about matching the headline or the lede to the content of the landing page, so that it meets their expectations. </p>
<p>If this sounds like a lot of work, <strong>it is</strong>! And there’s more to it yet, so schedule it and pace yourself.</p>
<h2 id="heading-different-landing-pages-and-their-analytics">Different Landing Pages and Their Analytics</h2>
<p>From your customer interviews, you should have a decent idea of your “Ideal Customer” (also called a <strong>persona</strong>). You should also have a good idea where they might be on other channels: where on social media; which other businesses have them on their email lists. You might then want to know how they found you, when they do come.</p>
<h3 id="heading-a-multi-channel-approach-to-landing-pages">A multi-channel approach to landing pages</h3>
<p>If you know your market well, you will have one primary “Ideal Customer” and up to two secondary. (Know what they have in common, and any powerful difference.) Also know if you have different goals, for example: buy the product, beta-test the app, or hand over their email (also known as lead generation).</p>
<p>The overlap, the difference, and the goals you have for each is the number of landing pages you should have. So if you have two goals for your landing pages, and two segments with an overlap, then you have at least three and up to six landing pages. </p>
<p>But <strong>start with the main segment and its goal</strong>, which would be lead generation (once you <em>can</em> send them a message, they can choose to download/buy from there). </p>
<p>After that landing page “engine” is working for you, if you want to broaden your reach, you can start creating the secondary landing pages.</p>
<p>There are different ways to get them to click through your landing page:</p>
<ul>
<li>Put the link in your personal/business email footer.</li>
<li>Mention it in a forum or a community Slack channel, if the conversation is relevant, you’ve already introduced yourself, and you’re participating in other ways.</li>
<li>Obviously, share it over social media (e.g. Facebook, Twitter, Reddit, Instagram)—this is a well-known route, but ditto above.</li>
<li>Use Facebook ads to broaden your campaign’s reach.</li>
<li>Create a QR code for the landing page and put it on a sticker, poster, flyer, or a sample of your work. Then pursue opportunities to get them noticed and into other people’s hands.</li>
<li>This is intimidating, but it can help your reach: Talk to relevant blogs and related business owners and ask them if they’ll let you write some content (or some other thing you can do for their customers), in exchange for a mention of your service on their website, linking to your landing page. <em>Do not baldly ask them to link to you, and don’t accept merely a post on social media.</em> SEO content and back-link strategies and social media posts are a trade in unequal goods. If you offer something of value that persists, you should get something in return that persists.</li>
</ul>
<h3 id="heading-if-your-productservice-is-ready-for-traction">If your product/service is ready for traction</h3>
<p>After the initial campaign (the first set of visitors) where you’ve caught and ironed out any technological or copy glitches for conversions, start submitting your project to prospective promoters and content aggregators. </p>
<p>Aggregate audiences are enthusiastic about tech, and you might find helpful people there. Concentrate on those closest to your target market. As a coder, one that you probably should have in mind is <a target="_blank" href="https://www.producthunt.co/">ProductHunt</a>.</p>
<p>Delay this step if you’re early in the design/build process. Do it when you’re about a month away from being ready, when you’ve got real features to whet their appetite, and an audience you can ask to support you. The reason is that you don’t own that channel or platform, and you might not be able to change or remove it once it’s announced.</p>
<h3 id="heading-analytics">Analytics</h3>
<p>After setting up more than one landing page, and more than a couple of channels, it helps to create a unique URL for each landing page (which is obvious) and the channel through which it gets seen, so you know what channel is working for you and which one is not. These are called campaign URLs, or UTMs.</p>
<p>Google Analytics has both <a target="_blank" href="https://support.google.com/analytics/answer/10917952#zippy=%2Cin-this-article">advice</a> and <a target="_blank" href="https://ga-dev-tools.google/ga4/campaign-url-builder/">a tool</a> for creating UTMs. You could also use a social media scheduling tool (like HootSuite, Buffer, SproutSocial, or MeetEdgar) that creates UTMs for each share. Kissmetrics is one that works within apps, if you’re offering an online service.</p>
<p>For all this to have meaning, it assumes your Google Analytics is set up. </p>
<p>You can skip Google Analytics and just rely on WordPress’s JetPack Stats to tell you the basics about your traffic. You could even skip the UTM stuff if you don’t care about the finer details of your sources (JetPack tells you the source of your traffic by domain and country). But it doesn’t hurt to set up your basic Google Analytics anyway, because then at least you’ll have data when you’re ready to learn more. </p>
<p>I once had a conversation with a non-profit webmaster who was quite busy with weekly, sometimes daily, blog postings and events. She had no idea about her reach and traffic, aside from on-forum and in-person group conversations, because she’d never set it up. This was a popular group, and surely she had a much bigger reach than she realized. </p>
<p>Setting up your analytics requires (less than!) a morning or an afternoon to get yourself in, oriented, and get the bits verified. After that, you can let it run without much intervention, and it will give you a wealth of information over time.</p>
<p>So don’t faff around and waste that opportunity, even if most of your traffic is driven by, for example, group members (like the non-profit). Everything is a learning process, so set yourself up to learn. (I would have loved to have known what their demographics were, as we share a customer persona, but she couldn’t tell me.)</p>
<p>Coupled, but not really, with Google Analytics is <strong>Search Console</strong>. You have to separately submit your root domain URL along with its XML map (you’ll find a WordPress plugin for that). It’s Search Console, not Google Analytics, that tells you the search terms a visitor used to end up on your site. You want to know these keywords, which are particularly useful if you’ll be writing a blog. </p>
<p>The campaign URLs (UTMs) I mentioned above help you see your best communication channels and your conversions. You can check conversions two ways:</p>
<ul>
<li><em>Good:</em> Look at each Landing-page-Channel UTM that registers a hit in your Google Analytics, and then check Mailchimp to see if it resulted in a subscribe. Actually, reverse that: check your Subscribers and then go see their analytics.*</li>
<li><p><em>Better:</em> Set up an Analytics “Behaviour Goal” for when they land on your “Thank You” page (next section). Then you’ll see who (OS, country, demographics) made it through the landing page to actually sign up, and from whence they came. </p>
</li>
<li><p>with a little digging and the right plug-in, you can make the Signup page part of the subscriber’s info, demonstrating when a campaign worked.</p>
</li>
</ul>
<h3 id="heading-whats-this-about-a-thank-you-page">What’s this about a Thank You page?</h3>
<p>To entice someone to enter into this email/product/service relationship with you, you may have offered them something more than just notification of when your project is ready. </p>
<p>If so, make it a show of goodwill that they’ll either benefit from now or in the future, or something they’ll truly enjoy. It could be an article, an eBook, access to your list’s previous emails (through a public archive), an event invitation, or something more whimsical.</p>
<p>With or without a freebie, thanking them for subscribing is the proper thing to do. It’s polite. It confirms the action they took succeeded. <strong>The fact that it gives you metrics is a convenient bonus.</strong></p>
<p>One of my mailing lists offers an action-packed newsletter (DIY projects, advice Q&amp;A, and resource links), but only after a certain threshold of subscribers have joined. On some of my pop-ups and blog posts, I mention in the CTA that there’s also a freebie. Once they subscribe, the form redirects to my “Thank You” page. Where they see a very large, cute picture of a red squirrel.</p>
<p>Here, this article is long! You deserve a break. Stop and gaze for a moment. I certainly do. Gaze, that is. I have a squirrel house on my property and a range of grey and black squirrels for endless entertainment. </p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Ed9bYzFUDAusFjgPwQ9Wag.jpeg" alt="1*Ed9bYzFUDAusFjgPwQ9Wag" width="465" height="600" loading="lazy">
<em>“Well… this is embarrassing. I don’t know quite how to thank you with a freebie yet for joining my mailing list…<strong>Oh, wait. Yes, I do.</strong>” (Photograph: Steward Ellet/Natural England/PA)</em></p>
<p>OK, enough gazing. </p>
<p><strong>The Thank You page is also a very opportune place to tell them what to expect from the list</strong>: “I’ll/We’ll send you an email…” “once a month, on or around the 14th.” “Somewhere in between two blog posts.” “Every Wednesday.” “Every six weeks.” “On a quarterly basis.” “When we have something big to announce.” <em>Knowing when to expect your mail helps them anticipate the time they’ll spend reading it.</em></p>
<p>And finally, because of double-opt-in confirmations being a good practice, <strong>it should tell them that once they confirm their subscription by email,</strong> they’ll receive their freebie in a separate email.</p>
<p>For example, in the copy below the squirrel, I tell them “If you reply to the confirmation email with your postal address, I’ll send you a packet of milkweed seeds.” My particular audience would find this delightful.</p>
<h3 id="heading-opt-in-form-submission-how-to">Opt-in form submission how-to</h3>
<p>Go back to your list integration module or plugin on your WordPress. Each mailing list provider provides HTML code for the opt-in form that you put into your Landing Page. The form submits the data to the mailing list service. </p>
<p>You <strong>must</strong> set it up at your email service provider (AKA mailing service) that a successful <strong>opt-in form submission redirects to a page on your site</strong> that says Thank You. Otherwise, a module may (or may not) appear saying “success.”</p>
<p>The Thank You freebie shouldn’t be available for direct download from the Thank You page, because even if you block the URL from being crawled by search engines, it opens you up to diluting the value of your freebie by making it too shareable (consider the effort of forwarding your email to a friend, versus posting the download page in Facebook group. Yeah, that!).</p>
<p>This means you’ll be creating your first Welcome/Onboard <strong>automation</strong> at your mailing service, that triggers when the subscriber confirms their opt-in. </p>
<p><strong>Note:</strong> You could send the freebie without the confirmation step, if you really want to skip it! But that’s not good practice, as <strong>Canadian and European legislation mandates clear opt-ins</strong>. If you’re marketing to the whole world, make sure your list is compliant. (The United States legislation is opt-out only, which makes people hesitant to share their email addresses.) </p>
<p>The Onboard automation could also ask them for more info about themselves so you can better respond to their interests. Examples I’ve used:</p>
<ul>
<li>“I’m interested in what you’re interested in, so if you update your list profile, tell me your hobbies, as well as your region.”</li>
<li>“We’re designing the software right now, and we have a few questions about where to focus our attention for the greatest impact. Would you kindly answer a short survey?”</li>
</ul>
<h2 id="heading-how-to-avoid-the-free-ick-factor">How to Avoid the Free = Ick Factor</h2>
<p>People expect a little bit of free these days, especially when trying software or information sources. But giving something away for free is still an issue for those of us who need a self-protective way of doing business. </p>
<p>People rightfully hesitate at these “free!” offers. You can’t get the download without the transaction, and so much of what’s “free” ends up being costly in time and attention or worse. </p>
<p>For example, most of us have made the mistake of opting in, then being hit with an email every day for the next two weeks, with an insinuation that we’re holding ourselves back (an insulting form of missing out) if we don’t buy before their deadline. <em>Hard sells are never worth it.</em> </p>
<p>You don’t want to be lumped in with those marketers when you’re offering something out of generosity or curiosity about your target market. And they can be <em>very</em> good at feigning generosity and curiosity towards their targets until time to cash in with a scarcity trap.</p>
<p>If you’re uncomfortable with sharing something of value straight off, try this: Develop a low-commitment preview or freebie, and then offer a promotion for those who are engaged. </p>
<p>E-commerce stores universally offer promo codes. Only give it to the people who are opening your emails, or communicating with you over your other channels. (Keep in mind that people who have iPhones will be “open” by default, even if they aren’t reading your mail. This came with Apple’s iOS 15 email security.) </p>
<p>If your list was a waitlist, don’t cold-announce the launch (“It’s here!”). Talk about the lead-up once or twice in the month before it happens. This will show you who’s engaged. (They don’t need to attend your webinar or launch party to be considered “engaged.” It’s nice, but be reasonable.) Don’t give away promos unless they’ve shown they’re warm.</p>
<p>For casual observers, including the subscribers who don’t open their emails, create or update the landing page on your website that offers it at the price that you think it’s worth. The CTA here would be “Buy” without the promo code.</p>
<p>Then, if you still want to use that page for lead generation, have a delayed pop-up: “Want this at the Friends-and-Family rate? Join us. (Next spaghetti dinner at your house!)”</p>
<h3 id="heading-avoiding-time-wasters-sales-prevention">Avoiding time-wasters (sales prevention)</h3>
<p>When using free <strong>products</strong> as an incentive to join your alpha, beta, or general list, sometimes you have to <em><strong>not</strong></em> get it out there. There are bystanders who enjoy getting freebies, satisfying curiosity, feeling informed. They’re well intentioned, but they’re not your market. At $5 of value, you can afford the publicity and community goodwill, but if it’s something of real cost and value, you’ll need to learn <strong>sales prevention</strong>.</p>
<p>Imagine you threw a party, and a stranger strolled in and headed right on over to the buffet. At a public event, you might expect that. Party crashers can sometimes be delightful, but their intentions and manners (e.g. zero interest in conversation) quickly show you who’s not. </p>
<p>So we’re back at the beginning again: who is your customer? You have to know you’re serving the people who need it (don’t assume, do customer interviews, and leave some room for surprises). </p>
<p>If you give your stuff away without vetting, you’ll get very little feedback. Fuzzy feedback will result in a product that doesn’t actually serve anyone, or a product they’ll play with, but not buy.</p>
<p>Here’s my case study: I was bored of seeing life-advice-on-the-internet and 300+ page bestsellers of writing prompts. Endless ponderous nonsense, only some of it good. I thought it would be a lot more action-oriented if I designed a life-planning workbook with 3 monthly agendas. I had a budget of $1000, so it was a limited print run. And I gave it away in exchange for a promise of design feedback. </p>
<p>But people who don’t use agendas, or who’ve tried but never stuck with one, ordered it anyway, out of curiosity or sheer impulsivity. They didn’t provide any feedback, so I’m sure several hundred dollars of paper went into the recycling. That was my fault for not filtering them out. </p>
<p>What I should have done for those people, which I later did, was an automated email series to walk them through the workbook without having the workbook. A motivated journaller would have gotten value out of it. </p>
<p>So what’s a reasonable sales prevention technique? </p>
<p>That’s relatively easy: it’s copy written to tell the reader the exact problem they’re having and how you’re solving it, that <em>doesn’t</em> try to alleviate any reasonable doubt that they’re the intended customer, so they can self-select out.</p>
<p>That kind of specificity is strangely absent from catch-all high-ticket marketing (who also distract by offering money-back guarantees that are often more specific than what they’re promising).</p>
<p>You could use a survey for this purpose, where the end of the survey is either an opt-in or a polite “no thanks” on either side. </p>
<p>If they’re design targets or beta testers, you can send them a final step (e.g. to join a Slack community, or a GitHub project for the code) in their List Confirmation email. This can ascertain they’re ready for the two-way street of communication (giving access to the project specifically so you can observe or solicit feedback). </p>
<p><strong>Build in obstacles.</strong> If they’re ordering a free product, then at least charge the shipping. (Or invert that: sell the product, ship for free!) If what you’re offering for free isn’t worth the $10 shipping, they’re not gonna take it seriously. Lesson learned. </p>
<p>A customer that has to invest in trying your solution will efficiently provide feedback about how it works, if it works at all. And if it really works? This is the customer who’ll buy and provide testimonials—and future customers.</p>
<p>Also keep in mind: people pay for things they don’t use <em>all the time</em>. Building a revenue model for your product is important for your business.</p>
<h2 id="heading-multiple-offerings-and-list-groups">Multiple Offerings and List Groups</h2>
<p>Hopefully, your new product or project is a stand-alone and you won’t need to group your subscribers. But if you work on multiple projects at a time, you may be juggling different groups.</p>
<p>I had two mailing lists for two different websites. One list was segmented into groups. One group was onboarded into a course-by-email, and another got a monthly PDF (the example I show in the accompanying video). Another group only heard from me when I made progress on a separate project.</p>
<p>Your landing pages have to be simple and targeted, so don’t batch the subscribers all together in your emails, talking about all the things you do. It confuses readers more than it helps anyone. Write to the groups separately (or, once your skills are advanced, use merge fields to show or hide email content depending on their group).</p>
<p>It can be difficult to assign new subscribers into the appropriate groups. You could do so based on the page that they opted in on. You can also ask them if they’re interested in more than one type of email.</p>
<p>Explore your email service provider to see how they recognize the page source of the signup, and how you can automate to put that subscriber into one of your groups. </p>
<p>A good multi-purpose plugin will make it as easy as possible for someone to sign up and get in the right group the first time. </p>
<p>In the accompanying video, I use the "MailChimp for WordPress" plugin to create a simple form for a landing page:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*BkBTrA_emICk6EBL0nRvng.png" alt="MC4WP's forms builder dialog box" width="800" height="400" loading="lazy">
<em>MC4WP's forms builder. You can see it in the accompanying video.</em></p>
<p>I then updated the form to one that has the list groups by project. I made it obvious which one they were about to join:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*jzSFEqe5bXKvMy837RFAYw.png" alt="A group-sorting opt-in form, with the default group highlighted" width="800" height="691" loading="lazy">
<em>A group-sorting opt-in form, with the default group highlighted</em></p>
<p>If the short code (…id="220") for this form is in multiple places in the website, they will all update upon saving the changes.</p>
<p><strong>Test your form on multiple devices and browsers after every plugin or WordPress update</strong>. If your form doesn’t work, they’ll bounce.</p>
<h2 id="heading-final-advice-for-beta-testers-and-the-video-intro">Final Advice for Beta Testers, and the Video Intro</h2>
<p>Before we get to the <em>(optional: WordPress-Mailchimp-oriented)</em> video, there’s a last bit of context that you might need. </p>
<p>If you’re using lead generation to find and stay in touch with <strong>alpha/beta testers</strong> of your project, <strong>the mailing list is necessary, but it is not enough</strong>. You’ll want to be in touch with them for design feedback. </p>
<p>If it’s a product, make sure they order it through your e-commerce module (one final obstacle that anyone can manage), and not via private communication (why would they evade the transaction? Red flag!). Collect and pass their information from the module through to Mailchimp.</p>
<p>And keep their details in a notebook, spreadsheet, email folder, etc. Reach out to them and set up phone, Skype, and Facetime conversations. Why? Because for real issues that affect your work, you have to interview these collaborative customers, sometimes more than once. </p>
<p>The video (from 2018) illustrates how you can set up a landing page, set up the welcome automations, and these attendant features:</p>
<ul>
<li>how WooCommerce integrates with MailChimp (for ecommerce orders for physical products or for downloads where you get paid)</li>
<li>what MailChimp looks like when you’re using groups or segments for automating messages and campaigns,</li>
<li>a demonstration of creating a landing page, using a MailChimp plugin to generate forms that use shortcodes (which can update changes across your site)</li>
<li>MailChimp’s own landing page generator</li>
<li>and finally, an intro to email automation. </li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/BK9iHnkr9nM" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-in-conclusion">In Conclusion</h2>
<p>My dear fellow idea/product creators and web developers, I now present you with the summary of the things I just explained.   </p>
<p>This article was about getting to know the people who are going to try out and adopt your idea, by getting them into a relationship with you. You’ll not only be learning how to address their needs with the thing you’re developing, but also where you can find them, and how they want to be communicated with.</p>
<p>Your communication is part of your Value Proposition as much as your product at this point. Everything is iterative, and you’ll learn as you go. Fortunately, a landing page is something people expect for just about any endeavour.</p>
<p>Create a landing page connected to your mailing list (not your social, not your home page) that tells people about the project and how it will help them. Induce them to get on the list— <em>unless it’s not for them</em>. Make sure your opt-ins are clear and, depending on the value you’re proposing, pre-qualified. </p>
<p>To increase your opt-ins, offer people something useful or delightful <em>right now</em>. Those bonuses or previews, and the mail you send after opt-in, creates and builds a relationship with them. In that light, make sure you can be reached by the lists’ reply-to address.</p>
<p>Use other channels such as partnership opportunities and events to raise your profile and direct people to your landing page. Use different copywriting for different channels. </p>
<p>Use different landing pages for different “Ideal Customer” personas and different goals (for example: sign up to the waitlist; download the app; beta-test; buy). </p>
<p>Set up your analytics so that once you start gaining traction–especially when aggregators and others promote your work–you’ll be able to know where they came from, what their demographics are, and what campaigns are working.</p>
<p>Treat your subscribers like clients and friends: be available to them, write to them in a personable manner, and keep it concise, helpful, meaningful, and enjoyable. Do <em>not</em> chase click metrics: chase providing value. </p>
<p>If they’re alpha or beta testers, reach out to them in person, ask non-leading questions, and follow up on any issues raised.</p>
<p>Finally, if you’re in the channels where your customers can be found, and these methods don’t get you the traction your project needs, that’s <em>incredibly valuable information.</em> <a target="_blank" href="https://www.ft.com/content/22b826cd-c451-4df7-b57d-af2e98258f7a">Quit it sooner rather than later!</a> You can pivot, or abandon it and start over again. You now know how. </p>
<p><em>Jane Sorensen has always been a multi-disciplinarian. She writes the words,</em> <a target="_blank" href="https://unsplash.com/@janerette"><em>takes the pictures</em></a><em>, handles the money, and drives the emergency backup Zamboni. If you’d like a dose of practical low-carbon lifestyle, DIY projects, and ecological gardening and wildlife enthusiasm, check out her blog at</em> <a target="_blank" href="http://bigcitylittlehomestead.ca"><em>bigcitylittlehomestead.ca</em></a><em>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
