Skip to content

Pages

Pages in Nimbu are incredibly flexible thanks to the canvas system and editable tags. You can build drag-and-drop page builders that empower content editors to create rich, custom layouts without touching code.

Canvas System

The canvas system transforms your page template into a drag-and-drop page builder where editors can:

  • Add content blocks from a library of components
  • Reorder blocks by dragging
  • Edit content within each block
  • Remove blocks they don't need
  • Duplicate successful sections

Basic Canvas Example

liquid
<div class="page-content">
  {% editable_canvas content %}
    {% repeatable "Text Block" %}
      {% include 'repeatables/text-block' %}
    {% endrepeatable %}

    {% repeatable "Text & Image" %}
      {% include 'repeatables/text-image' %}
    {% endrepeatable %}

    {% repeatable "Gallery" %}
      {% include 'repeatables/gallery' %}
    {% endrepeatable %}
  {% endeditable_canvas %}
</div>

When editors visit this page, they see an "+ Add Section" button offering "Text Block", "Text & Image", and "Gallery" options.

Complete Page Template with Canvas

Here's a real-world page template:

liquid
<article class="page">
  <header class="page-header">
    <div class="container">
      <h1>{{ page.title }}</h1>
      {% if page.excerpt %}
        <p class="lead">{{ page.excerpt }}</p>
      {% endif %}
    </div>
  </header>

  <div class="page-content">
    {% editable_canvas content %}
      {% repeatable "Full Width Text" %}
        {% include 'repeatables/full-text' %}
      {% endrepeatable %}

      {% repeatable "Text & Image" %}
        {% include 'repeatables/text-image' %}
      {% endrepeatable %}

      {% repeatable "Hero Section" %}
        {% include 'repeatables/hero' %}
      {% endrepeatable %}

      {% repeatable "Cards" %}
        {% include 'repeatables/cards' %}
      {% endrepeatable %}

      {% repeatable "Call to Action" %}
        {% include 'repeatables/cta' %}
      {% endrepeatable %}

      {% repeatable "Gallery" %}
        {% include 'repeatables/gallery' %}
      {% endrepeatable %}

      {% repeatable "Accordion" %}
        {% include 'repeatables/accordion' %}
      {% endrepeatable %}

      {% repeatable "Contact Form" %}
        {% include 'repeatables/contact-form' %}
      {% endrepeatable %}
    {% endeditable_canvas %}
  </div>
</article>

Repeatable Blocks

Repeatables are the building blocks of your canvas. Each repeatable is a component that editors can add to their pages.

Simple Text Block

snippets/repeatables/text-block.liquid:

liquid
<section class="text-block">
  <div class="container">
    {% editable_text content %}
      <p>Add your content here...</p>
    {% endeditable_text %}
  </div>
</section>

Text & Image Block

snippets/repeatables/text-image.liquid:

liquid
<section class="text-image-section">
  <div class="container">
    <div class="row align-items-center">
      <div class="col-md-6 {% if image_position == 'right' %}order-md-2{% endif %}">
        <div class="image-wrapper">
          {% editable_file image, label: "Image" %}
            {{ "placeholder-image.jpg" | theme_image_url }}
          {% endeditable_file %}
          {% editable_field image_alt, label: "Image Alt Text" %}{% endeditable_field %}
        </div>
      </div>

      <div class="col-md-6">
        <div class="text-wrapper">
          {% editable_field heading, label: "Heading" %}
            Section Heading
          {% endeditable_field %}

          {% editable_text content, label: "Content" %}
            <p>Add your content here...</p>
          {% endeditable_text %}

          {% editable_field button_text, assign: btn_text, label: "Button Text" %}{% endeditable_field %}
          {% editable_field button_link, assign: btn_link, label: "Button URL" %}{% endeditable_field %}

          {% if btn_link and btn_text %}
            <a href="{{ btn_link }}" class="btn btn-primary">{{ btn_text }}</a>
          {% endif %}
        </div>
      </div>
    </div>
  </div>
</section>

<!-- Section Settings -->
{% editable_group settings, label: "Section Settings" %}
  {% editable_select image_position,
    options: "left,right",
    labels: "Left,Right",
    assign: image_position,
    label: "Image Position"
  %}left{% endeditable_select %}

  {% editable_select background_color,
    options: "white,gray,dark",
    labels: "White,Gray,Dark",
    assign: bg_color,
    label: "Background Color"
  %}white{% endeditable_select %}

  {% editable_select vertical_alignment,
    options: "top,center",
    labels: "Top,Center",
    label: "Vertical Alignment"
  %}center{% endeditable_select %}
{% endeditable_group %}

Hero Section with All Features

snippets/repeatables/hero.liquid:

liquid
<section class="hero-section" style="background-image: url('{{ background_image }}');">
  <div class="hero-overlay" style="opacity: {{ overlay_opacity }}"></div>

  <div class="container">
    <div class="hero-content text-{{ text_alignment }}">
      {% editable_field heading, label: "Hero Heading" %}
        <h1>Hero Heading</h1>
      {% endeditable_field %}

      {% editable_text subheading, label: "Subheading" %}
        <p>Your compelling subheading goes here.</p>
      {% endeditable_text %}

      {% editable_field primary_button_text, assign: btn_text, label: "Primary Button Text" %}{% endeditable_field %}
      {% editable_field primary_button_link, assign: btn_link, label: "Primary Button URL" %}{% endeditable_field %}

      {% if btn_text and btn_link %}
        <a href="{{ btn_link }}" class="btn btn-lg btn-primary">{{ btn_text }}</a>
      {% endif %}

      {% editable_field secondary_button_text, assign: btn2_text, label: "Secondary Button Text" %}{% endeditable_field %}
      {% editable_field secondary_button_link, assign: btn2_link, label: "Secondary Button URL" %}{% endeditable_field %}

      {% if btn2_text and btn2_link %}
        <a href="{{ btn2_link }}" class="btn btn-lg btn-outline">{{ btn2_text }}</a>
      {% endif %}
    </div>
  </div>
</section>

<!-- Hero Settings -->
{% editable_group settings, label: "Hero Settings" %}
  {% editable_file background_image, assign: background_image, label: "Background Image", hint: "Recommended: 1920x1080px" %}
    {{ "hero-default.jpg" | theme_image_url }}
  {% endeditable_file %}

  {% editable_select text_alignment,
    options: "left,center,right",
    labels: "Left,Center,Right",
    assign: text_alignment,
    label: "Text Alignment"
  %}center{% endeditable_select %}

  {% editable_select overlay_opacity,
    options: "0,0.3,0.5,0.7",
    labels: "None,Light,Medium,Dark",
    assign: overlay_opacity,
    label: "Overlay Darkness"
  %}0.5{% endeditable_select %}

  {% editable_select text_color,
    options: "white,black",
    labels: "White,Black",
    assign: text_color,
    label: "Text Color"
  %}white{% endeditable_select %}
{% endeditable_group %}

Cards Grid with Nested Canvas

snippets/repeatables/cards.liquid:

liquid
<section class="cards-section">
  <div class="container">
    {% editable_field section_title, assign: title, label: "Section Title" %}{% endeditable_field %}

    {% if title %}
      <h2 class="section-title">{{ title }}</h2>
    {% endif %}

    <div class="cards-grid">
      {% editable_canvas cards %}
        {% repeatable "Card" %}
          <div class="card {{ card_style }}">
            <div class="card-icon">
              {% editable_file icon, label: "Icon" %}
                {{ "icon-placeholder.svg" | theme_image_url }}
              {% endeditable_file %}
            </div>

            <h3 class="card-title">
              {% editable_field title, label: "Title" %}Card Title{% endeditable_field %}
            </h3>

            <div class="card-text">
              {% editable_text description, label: "Description" %}
                <p>Card description goes here.</p>
              {% endeditable_text %}
            </div>

            {% editable_field link_url, assign: link, label: "Link URL" %}{% endeditable_field %}
            {% if link %}
              <a href="{{ link }}" class="card-link">Learn More →</a>
            {% endif %}
          </div>

          {% editable_group card_settings, label: "Card Settings" %}
            {% editable_select card_style,
              options: "default,outlined,elevated",
              labels: "Default,Outlined,Elevated",
              assign: card_style
            %}default{% endeditable_select %}
          {% endeditable_group %}
        {% endrepeatable %}
      {% endeditable_canvas %}
    </div>
  </div>
</section>

<!-- Section Settings -->
{% editable_group settings, label: "Section Settings" %}
  {% editable_select columns,
    options: "2,3,4",
    labels: "2 Columns,3 Columns,4 Columns",
    label: "Grid Columns"
  %}3{% endeditable_select %}

  {% editable_select background,
    options: "white,gray",
    labels: "White,Gray"
  %}white{% endeditable_select %}
{% endeditable_group %}

Editable Tags Reference

Nimbu provides 9 types of editable tags. Here's the complete reference:

1. editable_field

Single-line text input for short content like titles, button text, or simple values.

liquid
{% editable_field heading %}Default Title{% endeditable_field %}

<!-- With label and hint -->
{% editable_field button_text, label: "Button Text", hint: "Keep it short and actionable" %}
  Click Here
{% endeditable_field %}

<!-- Assign to variable for reuse -->
{% editable_field cta_text, assign: cta %}Get Started{% endeditable_field %}
{% if cta %}
  <button>{{ cta }}</button>
{% endif %}

Parameters:

  • label - Label shown in editor
  • hint - Help text for editors
  • assign - Store value in variable
  • default - Fallback if empty (deprecated, use content between tags instead)

2. editable_text

Rich text editor (WYSIWYG) for formatted content with headings, lists, links, and images.

liquid
{% editable_text content %}
  <p>Add your formatted content here...</p>
  <ul>
    <li>Support for lists</li>
    <li>Bold and italic text</li>
    <li>Links and images</li>
  </ul>
{% endeditable_text %}

<!-- With label -->
{% editable_text description, label: "Product Description", hint: "Describe the product features" %}
  <p>Default product description.</p>
{% endeditable_text %}

<!-- Assign to variable -->
{% editable_text intro, assign: intro_text %}
  <p>Introduction text...</p>
{% endeditable_text %}
<div class="wysiwyg">{{ intro_text }}</div>

3. editable_file

File upload for images, PDFs, or other assets. Returns the file URL.

liquid
{% editable_file image %}
  {{ "default-image.jpg" | theme_image_url }}
{% endeditable_file %}

<!-- With label and hint -->
{% editable_file logo, label: "Company Logo", hint: "Upload PNG or SVG (max 200KB)" %}
  {{ "logo.svg" | theme_image_url }}
{% endeditable_file %}

<!-- Assign to variable -->
{% editable_file hero_image, assign: bg_image, label: "Hero Background" %}
  {{ "hero-default.jpg" | theme_image_url }}
{% endeditable_file %}

<div class="hero" style="background-image: url('{{ bg_image }}')">
  <!-- Hero content -->
</div>

<!-- Use in image tag with filters -->
{% editable_file product_image, assign: img %}{{ "default.jpg" | theme_image_url }}{% endeditable_file %}
<img src="{{ img | filter, width: '800px', cropping: 'fill' }}" alt="Product">

4. editable_select

Dropdown selection for predefined choices.

liquid
{% editable_select theme, options: "light,dark", labels: "Light Theme,Dark Theme" %}
  light
{% endeditable_select %}

<!-- Assign to variable -->
{% editable_select alignment,
  options: "left,center,right",
  labels: "Left,Center,Right",
  assign: text_align,
  label: "Text Alignment"
%}center{% endeditable_select %}

<div class="text-{{ text_align }}">
  Content aligned {{ text_align }}
</div>

<!-- More options -->
{% editable_select size,
  options: "sm,md,lg,xl",
  labels: "Small,Medium,Large,Extra Large",
  label: "Section Size",
  hint: "Choose the section height"
%}md{% endeditable_select %}

<!-- Without labels (uses options as labels) -->
{% editable_select columns, options: "2,3,4", label: "Grid Columns" %}3{% endeditable_select %}

Parameters:

  • options - Comma-separated values (required)
  • labels - Comma-separated display names (optional, uses options if not provided)
  • label - Label shown in editor
  • hint - Help text
  • assign - Store selected value in variable

5. editable_switch

Boolean toggle for on/off settings.

liquid
{% editable_switch show_border %}false{% endeditable_switch %}

<!-- With label -->
{% editable_switch show_header, label: "Show Section Header", assign: show_header %}
  true
{% endeditable_switch %}

{% if show_header %}
  <header class="section-header">
    <h2>Section Title</h2>
  </header>
{% endif %}

<!-- Common uses -->
{% editable_switch enable_parallax, label: "Enable Parallax Effect" %}false{% endeditable_switch %}
{% editable_switch show_social_share, label: "Show Social Sharing" %}true{% endeditable_switch %}
{% editable_switch full_width, label: "Full Width Section" %}false{% endeditable_switch %}

6. editable_reference

Link to other content in Nimbu (pages, products, collections, channels, menus, customers).

liquid
<!-- Reference a page -->
{% editable_reference linked_page, to: "pages", label: "Related Page" %}{% endeditable_reference %}
{% if linked_page %}
  <a href="{{ linked_page.url }}">{{ linked_page.title }}</a>
{% endif %}

<!-- Reference a product -->
{% editable_reference featured_product, to: "products", label: "Featured Product" %}{% endeditable_reference %}
{% if featured_product %}
  <h3>{{ featured_product.name }}</h3>
  <p>{{ featured_product.price | money_with_currency }}</p>
  <a href="{{ featured_product.url }}">View Product</a>
{% endif %}

<!-- Reference a collection -->
{% editable_reference product_collection, to: "collections" %}{% endeditable_reference %}
{% if product_collection %}
  <a href="{{ product_collection.url }}">Shop {{ product_collection.name }}</a>
{% endif %}

<!-- Reference channel entry -->
{% editable_reference team_member, to: "team", label: "Team Member" %}{% endeditable_reference %}
{% if team_member %}
  <div class="team-member">
    <h4>{{ team_member.name }}</h4>
    <p>{{ team_member.bio }}</p>
  </div>
{% endif %}

<!-- Multiple references -->
{% editable_reference related_products, to: "products", multiple: true, label: "Related Products" %}{% endeditable_reference %}
{% if related_products %}
  <div class="related-products">
    {% for product in related_products %}
      {% include 'product-card', product: product %}
    {% endfor %}
  </div>
{% endif %}

Parameters:

  • to - Content type: "pages", "products", "collections", "channels", "menus", "customers", or a channel slug
  • multiple - Allow multiple selections (boolean)
  • label - Label shown in editor
  • hint - Help text

7. editable_group

Organize related editable fields into collapsible groups (settings panels).

liquid
{% editable_group settings, label: "Section Settings" %}
  {% editable_select background, options: "white,gray,dark" %}white{% editable_select %}
  {% editable_select spacing, options: "none,sm,md,lg" %}md{% endeditable_select %}
  {% editable_switch full_width %}false{% endeditable_switch %}
{% endeditable_group %}

<!-- Multiple groups for organization -->
{% editable_group appearance, label: "Appearance" %}
  {% editable_select theme, options: "light,dark" %}light{% endeditable_select %}
  {% editable_select border_style, options: "none,solid,dashed" %}none{% endeditable_select %}
{% endeditable_group %}

{% editable_group layout, label: "Layout Options" %}
  {% editable_select columns, options: "2,3,4" %}3{% endeditable_select %}
  {% editable_select alignment, options: "left,center,right" %}center{% endeditable_select %}
{% endeditable_group %}

{% editable_group advanced, label: "Advanced Settings" %}
  {% editable_field custom_css_class, label: "CSS Class" %}{% endeditable_field %}
  {% editable_field section_id, label: "Section ID" %}{% endeditable_field %}
{% endeditable_group %}

Best Practice: Use groups to organize settings, keeping main editable fields (content) separate from styling options.

8. editable_canvas

Create drag-and-drop areas where editors can add, reorder, and remove repeatable blocks.

liquid
{% editable_canvas content_blocks %}
  {% repeatable "Section Type 1" %}
    {% include 'repeatable-type-1' %}
  {% endrepeatable %}

  {% repeatable "Section Type 2" %}
    {% include 'repeatable-type-2' %}
  {% endrepeatable %}
{% endeditable_canvas %}

<!-- With label -->
{% editable_canvas features, label: "Product Features" %}
  {% repeatable "Feature" %}
    {% include 'feature-block' %}
  {% endrepeatable %}
{% endeditable_canvas %}

<!-- Nested canvas (canvas within repeatable) -->
{% editable_canvas sections %}
  {% repeatable "Container Section" %}
    <div class="container-section">
      {% editable_canvas nested_content %}
        {% repeatable "Text" %}
          {% include 'text-block' %}
        {% endrepeatable %}
        {% repeatable "Image" %}
          {% include 'image-block' %}
        {% endrepeatable %}
      {% endeditable_canvas %}
    </div>
  {% endrepeatable %}
{% endeditable_canvas %}

9. repeatable

Define content blocks that can be added multiple times within a canvas.

liquid
{% repeatable "Block Name" %}
  <!-- Block content with editable fields -->
{% endrepeatable %}

<!-- With label (displayed in UI) -->
{% repeatable "text_block", label: "Text Block" %}
  {% editable_text content %}
    <p>Text content...</p>
  {% endeditable_text %}
{% endrepeatable %}

<!-- Complete repeatable example -->
{% repeatable "testimonial", label: "Customer Testimonial" %}
  <div class="testimonial">
    {% editable_text quote, label: "Quote" %}
      <p>"Add customer testimonial here..."</p>
    {% endeditable_text %}

    {% editable_field customer_name, label: "Customer Name" %}
      John Doe
    {% endeditable_field %}

    {% editable_field customer_title, label: "Title/Company" %}
      CEO, Company Inc.
    {% endeditable_field %}

    {% editable_file customer_photo, label: "Photo" %}
      {{ "avatar-placeholder.jpg" | theme_image_url }}
    {% endeditable_file %}
  </div>
{% endrepeatable %}

Advanced Canvas Patterns

Conditional Repeatables

Show different repeatables based on template or context:

liquid
{% editable_canvas content %}
  {% repeatable "Text Block" %}
    {% include 'repeatables/text' %}
  {% endrepeatable %}

  {% if template == 'index' %}
    {% repeatable "Featured Products" %}
      {% include 'repeatables/featured-products' %}
    {% endrepeatable %}
  {% endif %}

  {% if customer %}
    {% repeatable "Personalized Content" %}
      {% include 'repeatables/personalized' %}
    {% endrepeatable %}
  {% endif %}

  {% repeatable "Call to Action" %}
    {% include 'repeatables/cta' %}
  {% endrepeatable %}
{% endeditable_canvas %}
liquid
{% repeatable "section", label: "Section" %}
  {% editable_field section_id, assign: section_id, label: "Section ID", hint: "For anchor links (e.g., #about)" %}{% endeditable_field %}

  <section {% if section_id %}id="{{ section_id | parameterize }}"{% endif %} class="content-section">
    {% editable_text content %}
      <p>Section content...</p>
    {% endeditable_text %}
  </section>
{% endrepeatable %}

Now editors can create anchor links: <a href="#about">Jump to About</a>

Spacing & Theme Controls

liquid
{% repeatable "flexible_section", label: "Flexible Section" %}
  <!-- Content -->
  {% editable_text content %}
    <p>Section content...</p>
  {% editable_text %}

  <!-- Settings -->
  {% editable_group settings, label: "Section Settings" %}
    {% editable_select spacing,
      options: "none,small,medium,large",
      labels: "No Spacing,Small,Medium,Large",
      assign: spacing
    %}medium{% editable_select %}

    {% editable_select theme,
      options: "light,dark,brand",
      labels: "Light,Dark,Brand Colors",
      assign: theme
    %}light{% editable_select %}
  {% endeditable_group %}

  <section class="section spacing-{{ spacing }} theme-{{ theme }}">
    <div class="container">
      {{ content }}
    </div>
  </section>
{% endrepeatable %}

Copywriting & Translation

Make editable content translatable across multiple languages using the {% translate %} tag.

Basic Translation

liquid
<button>
  {% translate 'cta.learn_more', default: 'Learn More' %}
</button>

<p>
  {% translate 'footer.copyright', default: 'All rights reserved' %}
</p>

Translation with Variables

liquid
{% translate 'cart.item_count',
  default: 'You have %{count} items in your cart',
  count: cart.items.size
%}

{% translate 'product.price_from',
  default: 'From %{price}',
  price: product.price | money_with_currency
%}

Editable + Translatable

Combine editable fields with translations:

liquid
{% editable_field welcome_key, assign: key %}welcome.title{% endeditable_field %}
<h1>{% translate key, default: 'Welcome' %}</h1>

Or wrap editable content:

liquid
<button>
  {% editable_field button_text %}
    {% translate 'cta.signup', default: 'Sign Up' %}
  {% endeditable_field %}
</button>

Managing Translations

Translations are managed in the Nimbu admin under Copywriting:

  1. Developer uses {% translate 'key.name', default: 'English Text' %}
  2. Nimbu creates copywriting entry with key key.name
  3. Content editors translate to other languages in admin
  4. Correct translation displays based on current locale

Complete Real-World Examples

Complete Page Template

Based on production themes:

liquid
<div class="page">
  {% editable_canvas content, label: "Page Content" %}
    {% repeatable "header", label: "Header" %}
      {% editable_field title, assign: title %}{% endeditable_field %}
      {% editable_field subtitle, assign: subtitle %}{% endeditable_field %}
      {% editable_field button_text, assign: btn_text %}{% endeditable_field %}
      {% editable_field button_link, assign: btn_link %}{% endeditable_field %}
      {% editable_file background_image, assign: bg_image %}{% endeditable_file %}

      {% editable_group advanced_settings, label: "Advanced Settings" %}
        {% editable_select background_overlay,
          options: "none,primary,secondary,dark",
          assign: bg_overlay
        %}none{% endeditable_select %}
        {% editable_select overlay_opacity,
          options: "transparent,light,normal,dark,opaque",
          assign: bg_overlay_opacity
        %}transparent{% endeditable_select %}
      {% endeditable_group %}

      {% include "repeatables/header",
        title: title,
        subtitle: subtitle,
        btn_text: btn_text,
        btn_link: btn_link,
        bg_image: bg_image,
        bg_overlay: bg_overlay,
        bg_overlay_opacity: bg_overlay_opacity
      %}
    {% endrepeatable %}

    {% repeatable "text", label: "Text" %}
      {% editable_text content, assign: text %}{% endeditable_text %}

      {% editable_group settings, label: "Settings" %}
        {% editable_select text_width,
          options: "small,default,large",
          labels: "Small,Default,Large",
          assign: text_width
        %}default{% endeditable_select %}

        {% editable_select columns,
          options: "1,2,3",
          labels: "1 Column,2 Columns,3 Columns",
          assign: text_columns
        %}1{% endeditable_select %}
      {% endeditable_group %}

      {% include "repeatables/text",
        text: text,
        text_columns: text_columns,
        text_width: text_width
      %}
    {% endrepeatable %}

    {% repeatable "text_with_image", label: "Text with Image" %}
      {% editable_text content, assign: text %}{% endeditable_text %}
      {% editable_file image, assign: image %}http://placehold.it/1000x600{% endeditable_file %}
      {% editable_field image_alt, assign: image_alt %}{% endeditable_field %}

      {% editable_group settings, label: "Settings" %}
        {% editable_select image_alignment,
          options: "left,right",
          labels: "Left Image,Right Image",
          assign: image_alignment
        %}left{% endeditable_select %}

        {% editable_select vertical_alignment,
          options: "top,center",
          labels: "Top,Center",
          assign: vertical_alignment
        %}center{% endeditable_select %}

        {% editable_select image_size,
          options: "small,default,large",
          labels: "Small,Default,Large",
          assign: image_size
        %}default{% endeditable_select %}
      {% endeditable_group %}

      {% include "repeatables/text-and-image",
        text: text,
        image: image,
        image_alt: image_alt,
        image_alignment: image_alignment,
        vertical_alignment: vertical_alignment,
        image_size: image_size
      %}
    {% endrepeatable %}

    {% repeatable "cards", label: "Cards" %}
      {% editable_group settings, label: "Settings" %}
        {% editable_select card_theme,
          options: "auto,primary,white,gray",
          labels: "Auto,Primary,White,Gray",
          assign: card_theme
        %}auto{% endeditable_select %}
      {% endeditable_group %}

      {% include 'repeatables/cards', card_theme: card_theme %}
    {% endrepeatable %}

    {% repeatable "contact_with_map", label: "Contact" %}
      {% editable_text content, assign: text %}{% endeditable_text %}
      {% editable_switch show_map, assign: show_map %}false{% endeditable_switch %}
      {% editable_field coordinates, assign: coordinates %}{% endeditable_field %}

      {% include "repeatables/contact",
        text: text,
        coordinates: coordinates,
        show_map: show_map
      %}
    {% endrepeatable %}
  {% endeditable_canvas %}
</div>

Best Practices

1. Always Provide Default Content

liquid
{% editable_field heading %}Default Heading{% endeditable_field %}

Never leave editable regions empty. Provide sensible defaults so pages look good before editing.

2. Use Meaningful Labels and Hints

liquid
{% editable_file logo, label: "Company Logo", hint: "Upload PNG or SVG (max 200KB, transparent background recommended)" %}

Help editors understand what each field is for and any requirements.

3. Organize with Groups

liquid
{% editable_group settings, label: "Section Settings" %}
  <!-- Group related settings -->
{% endeditable_group %}

Keep main content editable separate from styling/configuration options.

4. Use Assign for Conditional Logic

liquid
{% editable_field button_text, assign: btn_text %}{% endeditable_field %}
{% if btn_text %}
  <button>{{ btn_text }}</button>
{% endif %}

Only render elements when content exists.

5. Keep Repeat able Snippets Focused

Each repeatable should do one thing well. Don't create massive multi-purpose repeatables.

6. Test Empty States

Always test what happens when editors don't fill in optional fields.

7. Use References Instead of Text

liquid
<!-- Bad: Manual entry -->
{% editable_field product_url %}{% endeditable_field %}

<!-- Good: Reference -->
{% editable_reference featured_product, to: "products" %}{% endeditable_reference %}

References ensure links stay valid and provide better UX.

Common Patterns

Optional Sections

liquid
{% editable_switch show_section %}false{% endeditable_switch %}
{% if show_section %}
  <section>
    {% editable_text content %}
      <p>Content...</p>
    {% endeditable_text %}
  </section>
{% endif %}

Background Image Sections

liquid
{% editable_file bg_image, assign: bg %}{{ "default-bg.jpg" | theme_image_url %}{% endeditable_file %}
<section style="background-image: url('{{ bg | filter, width: '1920px' }}')">
  <!-- Content -->
</section>

Video Embeds

liquid
{% editable_field video_id, assign: video, label: "YouTube Video ID" %}{% endeditable_field %}
{% if video %}
  <div class="video-embed">
    <iframe src="https://www.youtube.com/embed/{{ video }}" allowfullscreen></iframe>
  </div>
{% endif %}

Troubleshooting

Content Not Saving

  • Check that editable tags are properly closed
  • Ensure unique field names within the same repeatable
  • Verify you're in edit mode in the Nimbu admin

Canvas Not Showing

  • Confirm {% editable_canvas %} and {% endeditable_canvas %} tags are balanced
  • Check that repeatables are inside the canvas
  • Ensure snippet paths are correct

Repeatables Not Appearing

  • Verify snippet exists at the specified path
  • Check for syntax errors in the repeatable snippet
  • Ensure {% include %} path matches snippet location

Next Steps

You now have the complete toolkit for building flexible, editable pages in Nimbu!