Skip to content

Advanced Features

Nimbu provides advanced features for search, authentication, analytics, payments, and security to build sophisticated web applications.

{% search %}

Built-in site search with filtering:

liquid
{% search params.q, in: 'products,pages,articles' %}
  {% if search.results.size > 0 %}
    <div class="search-results">
      <h2>Found {{ search.results.size }} results for "{{ params.q }}"</h2>

      {% for result in search.results %}
        <div class="result">
          <h3><a href="{{ result.url }}">{{ result.title }}</a></h3>
          <p>{{ result.excerpt | highlight: params.q }}</p>
          <span class="type">{{ result.type }}</span>
        </div>
      {% endfor %}
    </div>
  {% else %}
    <p>No results found for "{{ params.q }}"</p>
  {% endif %}
{% endsearch %}

Search Parameters:

  • in - Content types to search: products, pages, articles, channels
  • limit - Maximum results (default: 50)
  • locale - Search specific locale

Search Result Properties:

  • result.title - Result title
  • result.url - Result URL
  • result.excerpt - Text excerpt
  • result.type - Content type
  • result.score - Relevance score

OAuth Authentication

{% login_with %}

Social login integration:

liquid
{% login_with 'google', redirect_to: '/account' %}
<!-- Generates Google OAuth login button -->

{% login_with 'facebook', class: 'btn btn-primary' %}

{% login_with 'twitter', text: 'Sign in with Twitter' %}

Supported Providers:

  • google - Google OAuth
  • facebook - Facebook Login
  • twitter - Twitter OAuth
  • github - GitHub OAuth
  • linkedin - LinkedIn OAuth

Remove OAuth connection:

liquid
{% if customer.google_connected %}
  {% unlink_from 'google', text: 'Disconnect Google' %}
{% endif %}
liquid
{% oauth2_consent_form client_id: 'your_client_id' %}
<!-- Generates OAuth2 authorization form -->

Analytics Integration

Google Analytics

liquid
<!-- In layout head -->
{{ 'UA-XXXXX-Y' | google_analytics }}

<!-- Or with Google Analytics 4 -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
</script>

Google Tag Manager

liquid
{{ 'GTM-XXXXX' | gtm }}

Custom Event Tracking

liquid
<button
  onclick="gtag('event', 'add_to_cart', {
    'event_category': 'ecommerce',
    'event_label': '{{ product.name }}',
    'value': {{ product.price }}
  })">
  Add to Cart
</button>

Payment Integration

Stripe Checkout

liquid
{{ order | payment_form, provider: 'stripe' }}

Custom Stripe Integration:

liquid
<form id="payment-form">
  <div id="card-element"></div>
  <button type="submit">Pay {{ cart.total | money_with_currency }}</button>
</form>

<script src="https://js.stripe.com/v3/"></script>
<script>
  const stripe = Stripe('{{ site.stripe_public_key }}');
  const elements = stripe.elements();
  const card = elements.create('card');
  card.mount('#card-element');

  const form = document.getElementById('payment-form');
  form.addEventListener('submit', async (event) => {
    event.preventDefault();

    const {token} = await stripe.createToken(card);

    // Submit token to your payment endpoint
    fetch('/checkout/process', {
      method: 'POST',
      body: JSON.stringify({token: token.id}),
      headers: {'Content-Type': 'application/json'}
    });
  });
</script>

PayPal Integration

liquid
{% paypal_button price: product.price, item: product.name %}

Mollie Payments

liquid
{{ order | payment_form, provider: 'mollie' }}

Security Features

ReCAPTCHA

liquid
{% recaptcha site_key: 'your_recaptcha_site_key' %}

{% recaptcha_button 'Submit Form', site_key: 'your_site_key' %}

Form with ReCAPTCHA:

liquid
{% form channels.contact, class: 'contact-form' %}
  {% input 'name', required: true %}
  {% input 'email', as: 'email', required: true %}
  {% text_area 'message', required: true %}

  {% recaptcha site_key: site.recaptcha_key %}

  {% submit_tag 'Send Message' %}
{% endform %}

CSRF Protection

All forms automatically include CSRF tokens:

liquid
{% form model %}
  <!-- Automatic CSRF token included -->
{% endform %}

Manual CSRF token:

liquid
<form method="post">
  {% csrf_token %}
  <!-- form fields -->
</form>

GDPR-compliant cookie consent:

liquid
{% consent_manager %}
<!-- Renders cookie consent banner -->

Custom Consent Configuration:

liquid
{% consent_manager
  privacy_url: '/privacy-policy',
  cookie_url: '/cookie-policy',
  categories: 'necessary,analytics,marketing'
%}
liquid
<!-- Script loads only with consent -->
{{ 'analytics.js' | asset_url | script_tag, consent: 'analytics' }}

Practical Examples

Complete Search Page

liquid
<div class="search-page">
  <h1>Search</h1>

  <form action="/search" method="get" class="search-form">
    <input
      type="search"
      name="q"
      value="{{ params.q }}"
      placeholder="Search products, pages, articles..."
      required>

    <div class="search-filters">
      <label>
        <input type="checkbox" name="in[]" value="products" {% if params.in contains 'products' %}checked{% endif %}>
        Products
      </label>
      <label>
        <input type="checkbox" name="in[]" value="pages" {% if params.in contains 'pages' %}checked{% endif %}>
        Pages
      </label>
      <label>
        <input type="checkbox" name="in[]" value="articles" {% if params.in contains 'articles' %}checked{% endif %}>
        Articles
      </label>
    </div>

    <button type="submit">Search</button>
  </form>

  {% if params.q %}
    {% assign search_types = params.in | default: 'products,pages,articles' %}

    {% search params.q, in: search_types %}
      {% if search.results.size > 0 %}
        <div class="results-header">
          <p>{{ search.results.size }} results for "{{ params.q }}"</p>
        </div>

        <div class="search-results">
          {% for result in search.results %}
            <div class="result result-{{ result.type }}">
              <h3><a href="{{ result.url }}">{{ result.title | highlight: params.q }}</a></h3>

              <p class="excerpt">
                {{ result.excerpt | highlight: params.q }}
              </p>

              <div class="result-meta">
                <span class="type">{{ result.type }}</span>
                {% if result.price %}
                  <span class="price">{{ result.price | money_with_currency }}</span>
                {% endif %}
              </div>
            </div>
          {% endfor %}
        </div>
      {% else %}
        <div class="no-results">
          <p>No results found for "{{ params.q }}"</p>
          <p>Try different keywords or browse our categories.</p>
        </div>
      {% endif %}
    {% endsearch %}
  {% endif %}
</div>

Login Page with Social OAuth

liquid
<div class="login-page">
  <div class="login-container">
    <h2>Sign In</h2>

    <!-- Email/Password Login -->
    {% form customer, class: 'login-form' %}
      {% error_messages_for form_model %}

      <div class="form-group">
        {% input 'email', as: 'email', label: 'Email', required: true %}
      </div>

      <div class="form-group">
        {% input 'password', as: 'password', label: 'Password', required: true %}
      </div>

      <div class="form-actions">
        {% submit_tag 'Sign In', class: 'btn btn-primary btn-block' %}
        <a href="/forgot-password" class="forgot-password">Forgot password?</a>
      </div>
    {% endform %}

    <div class="social-login-separator">
      <span>Or sign in with</span>
    </div>

    <!-- Social Login Options -->
    <div class="social-login-buttons">
      {% login_with 'google', text: 'Continue with Google', class: 'btn btn-google' %}
      {% login_with 'facebook', text: 'Continue with Facebook', class: 'btn btn-facebook' %}
      {% login_with 'github', text: 'Continue with GitHub', class: 'btn btn-github' %}
    </div>

    <p class="register-link">
      Don't have an account? <a href="/register">Create one</a>
    </p>
  </div>
</div>

Account Settings with OAuth Connections

liquid
<div class="account-settings">
  <h2>Connected Accounts</h2>

  <div class="oauth-connections">
    <!-- Google -->
    <div class="connection">
      <div class="connection-info">
        <strong>Google</strong>
        {% if customer.google_connected %}
          <span class="status connected">Connected as {{ customer.google_email }}</span>
        {% else %}
          <span class="status">Not connected</span>
        {% endif %}
      </div>

      <div class="connection-actions">
        {% if customer.google_connected %}
          {% unlink_from 'google', text: 'Disconnect', class: 'btn btn-sm btn-danger' %}
        {% else %}
          {% login_with 'google', text: 'Connect', class: 'btn btn-sm btn-primary' %}
        {% endif %}
      </div>
    </div>

    <!-- Facebook -->
    <div class="connection">
      <div class="connection-info">
        <strong>Facebook</strong>
        {% if customer.facebook_connected %}
          <span class="status connected">Connected</span>
        {% else %}
          <span class="status">Not connected</span>
        {% endif %}
      </div>

      <div class="connection-actions">
        {% if customer.facebook_connected %}
          {% unlink_from 'facebook', text: 'Disconnect', class: 'btn btn-sm btn-danger' %}
        {% else %}
          {% login_with 'facebook', text: 'Connect', class: 'btn btn-sm btn-primary' %}
        {% endif %}
      </div>
    </div>
  </div>
</div>

Contact Form with ReCAPTCHA

liquid
<div class="contact-section">
  <h2>Contact Us</h2>

  {% form channels.contact, class: 'contact-form' %}
    {% error_messages_for form_model %}

    <div class="form-row">
      <div class="col-md-6">
        {% input 'first_name', label: 'First Name', required: true %}
      </div>
      <div class="col-md-6">
        {% input 'last_name', label: 'Last Name', required: true %}
      </div>
    </div>

    <div class="form-group">
      {% input 'email', as: 'email', label: 'Email', required: true %}
    </div>

    <div class="form-group">
      {% text_area 'message', rows: 6, label: 'Message', required: true %}
    </div>

    <!-- ReCAPTCHA -->
    <div class="form-group">
      {% recaptcha site_key: site.recaptcha_key %}
    </div>

    {% submit_tag 'Send Message', class: 'btn btn-primary' %}
  {% endform %}
</div>

Best Practices

1. Secure API Keys

liquid
<!-- ✅ Good: Use site configuration -->
{{ site.stripe_public_key }}

<!-- ❌ Bad: Hardcode keys -->
{{ 'pk_live_XXXXXXXX' }}

2. HTTPS for OAuth

All OAuth flows require HTTPS in production.

3. Validate Search Input

liquid
<!-- ✅ Good: Sanitize search query -->
{% assign safe_query = params.q | strip | truncate: 100 %}
{% search safe_query %}

<!-- ⚠️ Always validate user input -->
liquid
<!-- ✅ Good: Respect consent -->
{{ 'analytics.js' | script_tag, consent: 'analytics' %}

<!-- ❌ Bad: Track without consent -->
{{ 'analytics.js' | script_tag }}

Next Steps

Build advanced features with Nimbu!