npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ag-grid-url-sync

v0.3.0

Published

AG Grid URL Sync - Synchronize AG Grid text filters with URL parameters

Downloads

752

Readme

CI

AG Grid URL Sync

A lightweight TypeScript library for synchronizing AG Grid text and number filters with URL parameters, enabling shareable filter states through clean, human-readable URLs.

Features

  • 🔍 Complete text filter support - All 8 AG Grid text operations (contains, equals, not contains, not equal, starts with, ends with, blank, not blank)
  • 🔢 Complete number filter support - All 9 AG Grid number operations (equals, not equal, greater than, greater than or equal, less than, less than or equal, in range, blank, not blank)
  • 🔢 Complete date filter support - All 9 AG Grid date operations (equals, not equal, before, before or equal, after, after or equal, in range, blank, not blank) with strict ISO date validation (YYYY-MM-DD)
  • Grouped serialization - Package all filters into a single URL parameter with querystring, JSON, or base64 encoding
  • �🔗 Manual URL generation for sharing filter states
  • ↔️ Bidirectional sync between grid and URL
  • 🛠️ Framework agnostic - works with any AG Grid setup
  • ⚛️ React hook - dedicated useAGGridUrlSync with state management
  • 📝 Full TypeScript support with strict mode compliance
  • 🚦 Graceful error handling with configurable error callbacks
  • 🧹 Clean, human-readable URL format
  • ⚡ High performance - handles 100+ filters efficiently (<20ms)
  • 🔧 Configurable URL prefixes
  • 🛡️ Robust edge case handling (special characters, malformed URLs)
  • 📦 Lightweight bundle size (~3KB gzipped)

Supported Filter Types

Supports all AG Grid text, number, and date filter operations (26 total) with clean, human-readable URL parameters:

Text Filters (8 operations)

| Filter Type | Operation | URL Format | Example | Description | | ----------- | ------------ | ---------------------------- | -------------------------- | --------------------------- | | Text | Contains | f_column_contains=value | f_name_contains=john | Text contains value | | Text | Equals | f_column_eq=value | f_status_eq=active | Text equals value exactly | | Text | Not Contains | f_column_notContains=value | f_name_notContains=spam | Text does not contain value | | Text | Not Equal | f_column_neq=value | f_status_neq=inactive | Text does not equal value | | Text | Starts With | f_column_startsWith=value | f_email_startsWith=admin | Text starts with value | | Text | Ends With | f_column_endsWith=value | f_file_endsWith=.pdf | Text ends with value | | Text | Blank | f_column_blank=true | f_optional_blank=true | Field is empty/null | | Text | Not Blank | f_column_notBlank=true | f_required_notBlank=true | Field has any value |

Number Filters (9 operations)

| Filter Type | Operation | URL Format | Example | Description | | ----------- | --------------------- | ------------------------ | ------------------------ | ----------------------------- | | Number | Equals | f_column_eq=value | f_age_eq=30 | Number equals value exactly | | Number | Not Equal | f_column_neq=value | f_salary_neq=50000 | Number does not equal value | | Number | Greater Than | f_column_gt=value | f_experience_gt=5 | Number is greater than value | | Number | Greater Than or Equal | f_column_gte=value | f_score_gte=85 | Number is ≥ value | | Number | Less Than | f_column_lt=value | f_budget_lt=10000 | Number is less than value | | Number | Less Than or Equal | f_column_lte=value | f_hours_lte=40 | Number is ≤ value | | Number | In Range | f_column_range=min,max | f_age_range=25,45 | Number is between min and max | | Number | Blank | f_column_blank=true | f_bonus_blank=true | Field is empty/null | | Number | Not Blank | f_column_notBlank=true | f_salary_notBlank=true | Field has any numeric value |

Date Filters (9 operations)

| Filter Type | Operation | URL Format | Example | Description | | ----------- | --------------- | ------------------------------ | ------------------------------------------ | ----------------------------------------- | | Date | Equals | f_column_eq=YYYY-MM-DD | f_created_eq=2024-01-15 | Date equals value exactly | | Date | Not Equal | f_column_neq=YYYY-MM-DD | f_deadline_neq=2024-12-31 | Date does not equal value | | Date | Before | f_column_before=YYYY-MM-DD | f_deadline_before=2024-12-31 | Date is before value | | Date | Before or Equal | f_column_beforeEq=YYYY-MM-DD | f_archived_beforeEq=2024-12-31 | Date is before or equal to value | | Date | After | f_column_after=YYYY-MM-DD | f_created_after=2024-01-01 | Date is after value | | Date | After or Equal | f_column_afterEq=YYYY-MM-DD | f_updated_afterEq=2024-06-01 | Date is after or equal to value | | Date | In Range | f_column_daterange=start,end | f_period_daterange=2024-01-01,2024-12-31 | Date is between start and end (inclusive) | | Date | Blank | f_column_blank=true | f_deadline_blank=true | Date field is empty/null | | Date | Not Blank | f_column_notBlank=true | f_created_notBlank=true | Date field has any value |

🗓️ Date Format Note: Date filters require strict ISO format (YYYY-MM-DD). All date values are validated for real calendar dates, including leap years and month boundaries. Invalid or non-ISO dates will be rejected.

Filter Detection

The library automatically works with:

  • Text columns configured with filter: 'agTextColumnFilter'
  • Number columns configured with filter: 'agNumberColumnFilter'
  • Auto-detection based on cellDataType: 'number' configuration
  • Columns with filter: true (AG Grid's default text filter)
  • Any column where users apply text, number, or date-based filters
  • All AG Grid text, number, and date filter operations through the filter menu
  • Mixed filter types - combine text, number, and date filters in the same URL

URL Examples

Simple text filter:

https://app.com/data?f_name_contains=john

Simple number filter:

https://app.com/data?f_salary_gt=75000

Simple date filter:

https://app.com/data?f_created_eq=2024-01-15

Date range filter:

https://app.com/data?f_period_daterange=2024-01-01,2024-12-31

Date before/after filter:

https://app.com/data?f_deadline_before=2024-12-31&f_created_after=2024-01-01

Mixed text, number, and date filters:

https://app.com/data?f_name_contains=john&f_department_eq=Engineering&f_salary_gte=80000&f_age_range=25,45&f_created_after=2024-01-01

All date operations:

https://app.com/data?f_created_eq=2024-01-15&f_deadline_neq=2024-12-31&f_start_after=2024-01-01&f_end_before=2024-12-31&f_updated_afterEq=2024-06-01&f_archived_beforeEq=2024-12-31&f_period_daterange=2024-01-01,2024-12-31&f_optional_blank=true&f_required_notBlank=true

Blank operations (text, number, and date):

https://app.com/data?f_comments_blank=true&f_bonus_blank=true&f_name_notBlank=true&f_salary_notBlank=true&f_deadline_blank=true&f_created_notBlank=true

Installation

npm install ag-grid-url-sync

Usage

Importing the Library

The library provides two main entry points:

// Core functionality - works with any framework
import { createUrlSync } from 'ag-grid-url-sync'

// React hook - for React applications
import { useAGGridUrlSync } from 'ag-grid-url-sync/react'

// TypeScript types (available from both imports)
import type { FilterState, AGGridUrlSyncConfig } from 'ag-grid-url-sync'

Tree-Shaking & Granular Imports

For optimal bundle sizes, you can import only the specific utilities you need:

import {
  validateFilterValue,
  DEFAULT_CONFIG
} from 'ag-grid-url-sync/validation'

import { parseUrlFilters, parseFilterParam } from 'ag-grid-url-sync/url-parser'

import { serializeFilters, generateUrl } from 'ag-grid-url-sync/url-generator'

import {
  getFilterModel,
  applyFilterModel
} from 'ag-grid-url-sync/grid-integration'

import type {
  FilterState,
  ColumnFilter,
  FilterOperation
} from 'ag-grid-url-sync/types'

Bundle Size Comparison

| Import Pattern | Bundle Size | Use Case | | ---------------- | ----------- | ---------------------- | | Full library | 5KB | Complete functionality | | Core class only | 3.2KB | Basic URL sync | | React hook only | 7KB | React applications | | URL parsing only | 1.05KB | Parse existing URLs | | Validation only | 318B | Input validation | | Types only | 0B | TypeScript types |

Example: Custom URL Parser

import { parseUrlFilters } from 'ag-grid-url-sync/url-parser'
import { DEFAULT_CONFIG } from 'ag-grid-url-sync/validation'
import type { FilterState } from 'ag-grid-url-sync/types'

function getFiltersFromUrl(url: string): FilterState {
  const config = {
    gridApi: null, // Not needed for parsing
    ...DEFAULT_CONFIG,
    onParseError: error => console.error('Parse error:', error)
  }

  return parseUrlFilters(url, config)
}

Example: Custom URL Generator

import { generateUrl, serializeFilters } from 'ag-grid-url-sync/url-generator'
import type { FilterState } from 'ag-grid-url-sync/types'

function createShareableUrl(filters: FilterState, baseUrl: string): string {
  const config = {
    gridApi: null, // Not needed for generation
    paramPrefix: 'f_',
    maxValueLength: 200,
    onParseError: () => {}
  }

  return generateUrl(baseUrl, filters, config)
}

💡 Pro Tip: Use granular imports in libraries and applications where bundle size matters. All existing import patterns remain fully supported for backward compatibility.

Basic Example

import { createUrlSync } from 'ag-grid-url-sync'

// Initialize with AG Grid API
const urlSync = createUrlSync(gridApi)

// Generate shareable URL with current filters (text and number)
const shareableUrl = urlSync.generateUrl()
// Result: https://app.com/data?f_name_contains=john&f_salary_gte=80000&f_age_range=25,45

// Apply filters from URL (automatically detects text vs number columns)
urlSync.applyFromUrl(
  'https://app.com/data?f_name_contains=manager&f_salary_gt=75000'
)

// Apply specific filter programmatically
urlSync.applyFilters({
  name: { filterType: 'text', type: 'contains', filter: 'john' },
  salary: { filterType: 'number', type: 'greaterThan', filter: 75000 },
  age: { filterType: 'number', type: 'inRange', filter: 25, filterTo: 45 }
})

// Clear all text and number filters
urlSync.clearFilters()

Grouped Serialization

Grouped serialization provides an alternative to individual URL parameters by packaging all filters into a single URL parameter. This is particularly useful for applications with many filters or when you need more compact URLs.

Why Use Grouped Serialization?

Individual serialization (default):

https://app.com/data?f_name_contains=john&f_age_gt=25&f_salary_gte=80000&f_created_after=2024-01-01

Grouped serialization:

https://app.com/data?grid_filters=f_name_contains%3Djohn%26f_age_gt%3D25%26f_salary_gte%3D80000%26f_created_after%3D2024-01-01

Benefits of grouped serialization:

  • Cleaner URLs with a single parameter instead of many

  • Better for sharing - easier to copy/paste and less prone to URL manipulation

  • Format flexibility - choose between querystring, JSON, or base64 encoding

  • Future-proof - easier to extend with additional metadata

Configuration

interface AGGridUrlSyncConfig {
  // Serialization mode
  serialization?: 'individual' | 'grouped' // default: 'individual'

  // Format for grouped serialization
  format?: 'querystring' | 'json' | 'base64' // default: 'querystring'

  // Parameter name for grouped mode
  groupedParam?: string // default: 'grid_filters'

  // ... other existing options
}

Format Options

QueryString Format (Default)

Filters are URL-encoded as a query string within the parameter:

const urlSync = createUrlSync(gridApi, {
  serialization: 'grouped',
  format: 'querystring' // default
})

// Result: ?grid_filters=f_name_contains%3Djohn%26f_age_gt%3D25
// Decoded: f_name_contains=john&f_age_gt=25

JSON Format

Filters are JSON-encoded, ideal for complex filter states:

const urlSync = createUrlSync(gridApi, {
  serialization: 'grouped',
  format: 'json'
})

// Result: ?grid_filters=%7B%22name%22%3A%7B%22filterType%22%3A%22text%22...
// Decoded: {"name":{"filterType":"text","type":"contains","filter":"john"}...}

Base64 Format

Filters are JSON-encoded then base64-encoded for maximum compactness:

const urlSync = createUrlSync(gridApi, {
  serialization: 'grouped',
  format: 'base64'
})

// Result: ?grid_filters=eyJuYW1lIjp7ImZpbHRlclR5cGUiOiJ0ZXh0Ii...
// Most compact representation, ideal for sharing

Basic Usage

import { createUrlSync } from 'ag-grid-url-sync'

// Basic grouped serialization
const urlSync = createUrlSync(gridApi, {
  serialization: 'grouped'
})

// Generate grouped URL
const url = urlSync.generateUrl('https://app.com/data')
// Result: https://app.com/data?grid_filters=f_name_contains%3Djohn%26f_age_gt%3D25

// Apply filters from grouped URL
urlSync.applyFromUrl(url)

// Get current serialization mode and format
console.log(urlSync.getSerializationMode()) // 'grouped'
console.log(urlSync.getCurrentFormat()) // 'querystring'

Advanced Examples

Format Conversion Utility

// Convert current filters to any format
const jsonFormat = urlSync.getFiltersAsFormat('json')
const base64Format = urlSync.getFiltersAsFormat('base64')
const querystringFormat = urlSync.getFiltersAsFormat('querystring')

console.log('JSON:', jsonFormat)
console.log('Base64:', base64Format)
console.log('QueryString:', querystringFormat)

Dynamic Format Switching

// Start with individual mode
const urlSync = createUrlSync(gridApi, {
  serialization: 'individual'
})

// Switch to grouped mode when needed
const groupedSync = createUrlSync(gridApi, {
  serialization: 'grouped',
  format: 'base64',
  groupedParam: 'filters'
})

// Use utility to maintain filters across mode changes
const currentFilters = urlSync.getFiltersAsFormat('json')

Granular Import: Grouped Serialization

You can import grouped serialization utilities and format serializers directly for advanced use cases or custom integrations:

import {
  serializeGrouped,
  deserializeGrouped
} from 'ag-grid-url-sync/serialization'
import {
  QueryStringSerializer,
  JsonSerializer,
  Base64Serializer
} from 'ag-grid-url-sync/serialization/formats'

Error Handling for Grouped Serialization

You can provide a custom error handler to gracefully handle malformed grouped parameters or serialization errors. The library will throw an InvalidSerializationError for invalid formats:

import { InvalidSerializationError } from 'ag-grid-url-sync/types'

const urlSync = createUrlSync(gridApi, {
  serialization: 'grouped',
  format: 'json',
  onParseError: error => {
    if (error instanceof InvalidSerializationError) {
      // Handle grouped serialization error
      alert('Invalid filter data in URL!')
    } else {
      // Handle other errors
      console.error(error)
    }
  }
})

Exports

The package supports granular subpath exports for advanced usage and optimal bundle size:

  • ag-grid-url-sync/serialization – grouped serialization utilities
  • ag-grid-url-sync/serialization/formats – format-specific serializers
  • ag-grid-url-sync/validation – validation helpers
  • ag-grid-url-sync/url-parser – URL parsing utilities
  • ag-grid-url-sync/url-generator – URL generation utilities
  • ag-grid-url-sync/grid-integration – AG Grid integration helpers
  • ag-grid-url-sync/types – TypeScript types

Refer to the package.json for the full export map.

React Integration

For React applications, use the dedicated useAGGridUrlSync hook that provides a complete solution with React-specific features and state management.

Installation for React

npm install ag-grid-url-sync

Basic React Usage

import React, { useState } from 'react'
import { AgGridReact } from 'ag-grid-react'
import { useAGGridUrlSync } from 'ag-grid-url-sync/react'

function GridComponent() {
  const [gridApi, setGridApi] = useState(null)

  const {
    shareUrl,
    applyUrlFilters,
    clearFilters,
    hasFilters,
    isReady,
    currentUrl
  } = useAGGridUrlSync(gridApi, {
    autoApplyOnMount: true,
    paramPrefix: 'filter_'
  })

  const handleShare = async () => {
    const url = shareUrl()
    await navigator.clipboard.writeText(url)
    alert('Filter URL copied!')
  }

  return (
    <div>
      <div style={{ marginBottom: '10px' }}>
        <button onClick={handleShare} disabled={!isReady}>
          📋 Share Filters
        </button>
        <button onClick={clearFilters} disabled={!hasFilters}>
          🗑️ Clear Filters
        </button>
        <button onClick={applyUrlFilters}>🔄 Apply URL Filters</button>
      </div>

      <div className="ag-theme-alpine" style={{ height: 400, width: '100%' }}>
        <AgGridReact
          onGridReady={params => setGridApi(params.api)}
          rowData={rowData}
          columnDefs={[
            {
              field: 'name',
              filter: 'agTextColumnFilter',
              floatingFilter: true
            },
            {
              field: 'email',
              filter: 'agTextColumnFilter',
              floatingFilter: true
            },
            {
              field: 'salary',
              filter: 'agNumberColumnFilter',
              floatingFilter: true
            },
            {
              field: 'age',
              filter: 'agNumberColumnFilter',
              floatingFilter: true
            }
          ]}
          defaultColDef={{
            flex: 1,
            sortable: true,
            resizable: true
          }}
        />
      </div>
    </div>
  )
}

React Hook API

useAGGridUrlSync(gridApi, options?)

import { useAGGridUrlSync } from 'ag-grid-url-sync/react'

const {
  shareUrl,
  getQueryParams,
  applyUrlFilters,
  clearFilters,
  isReady,
  currentUrl,
  hasFilters,
  parseUrlFilters,
  applyFilters,
  getFiltersAsFormat,
  getCurrentFormat
} = useAGGridUrlSync(gridApi, options)

Hook Options

interface UseAGGridUrlSyncOptions {
  // Core options (same as createUrlSync)
  paramPrefix?: string // Default: 'f_'
  maxValueLength?: number // Default: 200
  onParseError?: (error: Error) => void

  // React-specific options
  autoApplyOnMount?: boolean // Default: false
  enabledWhenReady?: boolean // Default: true
  onError?: (error: Error, context: string) => void // Advanced error handling
}

Hook Return Values

| Property | Type | Description | | -------------------- | -------------------------------- | ----------------------------------------------- | ---------------------------------------------------------- | -------------------------------------------------------------- | | shareUrl | (baseUrl?: string) => string | Generate shareable URL with current filters | | getQueryParams | () => string | Get filter state as query parameters | | applyUrlFilters | (url?: string) => void | Apply filters from URL to grid | | clearFilters | () => void | Clear all text filters | | isReady | boolean | Whether grid API is available and hook is ready | | currentUrl | string | Current URL with filters applied | | hasFilters | boolean | Whether grid has any active text filters | | parseUrlFilters | (url: string) => FilterState | Parse filters from URL without applying | | applyFilters | (filters: FilterState) => void | Apply filter state object to grid | | getFiltersAsFormat | (format: 'querystring' | 'json' | 'base64') => string | Serialize filters to any supported format (for sharing/export) | | getCurrentFormat | () => 'individual' | 'grouped' | Get the current serialization mode (individual or grouped) |

Note: getFiltersAsFormat and getCurrentFormat are especially useful for grouped serialization, format conversion, and advanced sharing scenarios.

React Features

  • 🔄 Automatic State Management: Tracks grid state and filter changes automatically
  • ⚡ Ready State: isReady indicates when the grid API is available
  • 🎯 Auto-Apply: autoApplyOnMount applies URL filters when component mounts
  • 🧹 Cleanup: Automatically cleans up resources when component unmounts
  • 🛡️ Error Boundaries: Graceful error handling with configurable callbacks
  • 📊 Filter Status: hasFilters tracks whether any filters are active

React with Grouped Serialization

The React hook fully supports grouped serialization with all format options:

import React, { useState } from 'react'
import { AgGridReact } from 'ag-grid-react'
import { useAGGridUrlSync } from 'ag-grid-url-sync/react'

function AdvancedGridComponent() {
  const [gridApi, setGridApi] = useState(null)

  // Grouped serialization with base64 format
  const { shareUrl, applyUrlFilters, clearFilters, hasFilters, isReady } =
    useAGGridUrlSync(gridApi, {
      serialization: 'grouped',
      format: 'base64',
      groupedParam: 'grid_state',
      autoApplyOnMount: true
    })

  const handleShareCompact = async () => {
    // Base64 format creates very compact URLs
    const url = shareUrl()
    await navigator.clipboard.writeText(url)
    alert('Compact filter URL copied!')
  }

  const handleShareJSON = async () => {
    // Get filters in JSON format for debugging
    const jsonFilters = urlSync?.getFiltersAsFormat?.('json')
    console.log('Current filters as JSON:', jsonFilters)
  }

  return (
    <div>
      <div style={{ marginBottom: '10px' }}>
        <button onClick={handleShareCompact} disabled={!isReady}>
          📋 Share Compact URL
        </button>
        <button onClick={handleShareJSON} disabled={!isReady}>
          🔍 Debug Filters
        </button>
        <button onClick={clearFilters} disabled={!hasFilters}>
          🗑️ Clear Filters
        </button>
      </div>

      {/* Grid component */}
      <div className="ag-theme-alpine" style={{ height: 400, width: '100%' }}>
        <AgGridReact
          onGridReady={params => setGridApi(params.api)}
          // ... grid configuration
        />
      </div>
    </div>
  )
}

Advanced React Example

import React, { useState, useEffect } from 'react'
import { useAGGridUrlSync } from 'ag-grid-url-sync/react'

function AdvancedGridComponent() {
  const [gridApi, setGridApi] = useState(null)
  const [shareMessage, setShareMessage] = useState('')

  const {
    shareUrl,
    applyUrlFilters,
    clearFilters,
    hasFilters,
    isReady,
    currentUrl,
    parseUrlFilters
  } = useAGGridUrlSync(gridApi, {
    autoApplyOnMount: true,
    paramPrefix: 'emp_',
    maxValueLength: 100,
    onParseError: error => {
      console.warn('Filter parsing error:', error.message)
      setShareMessage('Invalid filter URL detected')
    }
  })

  // Watch for URL changes
  useEffect(() => {
    if (currentUrl !== window.location.href) {
      setShareMessage('Filters have changed - URL ready to share')
    }
  }, [currentUrl])

  const handleShareToEmail = () => {
    const url = shareUrl()
    const subject = 'Check out this filtered data'
    const body = `View the filtered data here: ${url}`
    window.open(
      `mailto:?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`
    )
  }

  const handlePreviewFilters = () => {
    const url = prompt('Enter URL to preview filters:')
    if (url) {
      const filters = parseUrlFilters(url)
      console.log('Parsed filters:', filters)
      alert(`Found ${Object.keys(filters).length} filter(s)`)
    }
  }

  return (
    <div>
      <div className="controls">
        <button onClick={handleShareToEmail} disabled={!isReady}>
          📧 Share via Email
        </button>
        <button onClick={handlePreviewFilters}>👁️ Preview URL Filters</button>
        <button onClick={clearFilters} disabled={!hasFilters}>
          Clear ({hasFilters ? 'has filters' : 'no filters'})
        </button>
      </div>

      {shareMessage && <div className="message">{shareMessage}</div>}

      {/* Grid component */}
    </div>
  )
}

URL Format

The library generates clean, human-readable URLs:

Base URL: https://app.com/page
With text filters: https://app.com/page?f_name_contains=john&f_status_eq=active
With number filters: https://app.com/page?f_salary_gte=75000&f_age_range=25,45
Mixed filters: https://app.com/page?f_name_contains=john&f_salary_gte=75000&f_age_lt=50

Parameter structure:

  • Prefix: f_ (configurable)
  • Format: f_{columnName}_{operation}={value}
  • Text Operations: contains, eq, neq, startsWith, endsWith, notContains, blank, notBlank
  • Number Operations: eq, neq, gt, gte, lt, lte, range, blank, notBlank
  • Date Operations: eq, neq, before, beforeEq, after, afterEq, daterange, blank, notBlank
  • Range Format: f_column_range=min,max (comma-separated values)
  • Standard URL encoding for special characters
  • Supports column names with underscores (e.g., user_id, salary_base, created_date)

API Reference

createUrlSync(gridApi, config?)

Factory function to create a new AGGridUrlSync instance.

import { createUrlSync } from 'ag-grid-url-sync'

const urlSync = createUrlSync(gridApi, {
  paramPrefix: 'f_', // Default: 'f_'
  maxValueLength: 200, // Default: 200
  onParseError: err => console.warn(err)
})

AGGridUrlSync Class

Constructor

new AGGridUrlSync(gridApi: GridApi, config?: AGGridUrlSyncConfig)

Methods

generateUrl(baseUrl?: string): string

Generates a URL with the current filter state.

const url = urlSync.generateUrl('https://app.com/page')
// https://app.com/page?f_name_contains=john
getQueryParams(): string

Gets the current filter state as URL query parameters.

const params = urlSync.getQueryParams()
// ?f_name_contains=john
applyFromUrl(url?: string): void

Applies filters from a URL to the grid.

urlSync.applyFromUrl('https://app.com/page?f_name_contains=john')
applyFilters(filterState: FilterState): void

Applies a filter state object to the grid.

urlSync.applyFilters({
  name: {
    filterType: 'text',
    type: 'contains',
    filter: 'john'
  }
})
clearFilters(): void

Clears all text filters from the grid.

urlSync.clearFilters()
destroy(): void

Cleans up any resources or event listeners.

urlSync.destroy()

Configuration

interface AGGridUrlSyncConfig {
  // Serialization mode (default: 'individual')
  // 'individual': Each filter becomes a separate URL parameter
  // 'grouped': All filters are packaged into a single URL parameter
  serialization?: 'individual' | 'grouped'

  // Format for grouped serialization (default: 'querystring')
  // 'querystring': URL-encoded querystring format (most compatible)
  // 'json': JSON-encoded format (good for complex filters)
  // 'base64': Base64-encoded JSON (most compact)
  format?: 'querystring' | 'json' | 'base64'

  // Parameter name for grouped mode (default: 'grid_filters')
  groupedParam?: string

  // Prefix for URL parameters (default: 'f_')
  // In grouped mode, this affects individual parameter names within the group
  paramPrefix?: string

  // Maximum length for filter values (default: 200)
  maxValueLength?: number

  // Optional error handler for parsing errors
  // Called when URLs contain invalid filter parameters
  onParseError?: (error: Error) => void
}

Examples

Check out the examples directory for comprehensive working demos:

🚀 Vanilla JavaScript Demo

Comprehensive demonstration showcasing all features:

  • Complete text filter support - All 8 AG Grid text operations (contains, equals, not contains, not equal, starts with, ends with, blank, not blank)
  • Complete number filter support - All 9 AG Grid number operations (equals, not equal, greater than, greater than or equal, less than, less than or equal, in range, blank, not blank)
  • Complete date filter support - All 9 AG Grid date operations (equals, not equal, before, before or equal, after, after or equal, in range, blank, not blank)
  • Grouped serialization - Package all filters into a single URL parameter with querystring, JSON, or base64 encoding
  • Manual URL generation - Generate shareable URLs with current filter states
  • Bidirectional sync - Automatic synchronization between AG Grid and URL
  • Framework agnostic - Works with any AG Grid setup, no dependencies
  • High performance - Efficiently handles 100+ filters with <20ms latency
  • Robust error handling - Graceful handling of malformed URLs and special characters
  • Lightweight - Minimal bundle size (~3KB gzipped), ideal for modern web applications

⚛️ React Integration

Clean React component showing the useAGGridUrlSync hook:

  • React hook integration with AG Grid for text, number, and date filters
  • Automatic filter state management for mixed filter types
  • Share button with clipboard functionality
  • Filter status indicators and controls
  • Auto-apply filters on component mount with all filter types
  • Enhanced employee data with salary, age, and experience columns
  • Full TypeScript support with comprehensive type coverage

📊 Shared Data

Common data and column definitions used across examples:

  • Enhanced employee data with salary, age, and experience number fields
  • Project data with budget and numeric fields for comprehensive testing
  • Column definitions with complete text, number, and date filter support
  • All 8 text filter operations, 9 number filter operations, and 9 date filter operations enabled
  • Realistic data ranges for demonstrating number and date filters (salaries $58K-$95K, ages 26-42, experience 3-15 years)
  • Includes null values for demonstrating blank/notBlank operations

All examples work out-of-the-box and demonstrate the complete functionality. The HTML demo can be opened directly in your browser, while the React example shows clean integration patterns.

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

banner