Nimbu Developer Docs
Other

Advanced Features

Search, OAuth authentication, analytics integration, payment gateways, and security features

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

{% search %}

Built-in site search with filtering:

{% 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:

{% 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:

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

Analytics Integration

Google Analytics

<!-- 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

{{ 'GTM-XXXXX' | gtm }}

Custom Event Tracking

<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

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

Custom Stripe Integration:

<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

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

Mollie Payments

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

Security Features

ReCAPTCHA

{% recaptcha site_key: 'your_recaptcha_site_key' %}

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

Form with ReCAPTCHA:

{% 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:

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

Manual CSRF token:

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

GDPR-compliant cookie consent:

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

Custom Consent Configuration:

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

Practical Examples

Complete Search Page

<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

<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

<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

<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

<!-- ✅ 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

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

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

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

Next Steps

Build advanced features with Nimbu!

On this page