Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Aggrid Bundle Laravel Package

stinger-soft/aggrid-bundle

A Symfony bundle that integrates ag-Grid, offering Twig helpers, PHP data providers, and AJAX endpoints to build interactive, server-side powered data tables with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

First thing to understand: this is a Symfony bundle, not a Laravel package. There is no service provider, no config/aggrid.php, no facade. composer require stinger-soft/aggrid-bundle in a Laravel app will install code that never boots. As a Laravel developer, the realistic paths are:

  1. Read the bundle's src/ to steal the GridBuilder / ColumnType / DataProvider pattern and re-implement it as a small Laravel package (this is the high-value move — the pattern is genuinely good and maps cleanly onto Laravel).
  2. Run it inside a Symfony sidecar (or a Symfony app you already maintain) and talk to it over HTTP.
  3. Skip it and use a JS-only ag-Grid setup with a Laravel JSON endpoint.

If you do have a Symfony host app, the minimal setup is:

composer require stinger-soft/aggrid-bundle
// config/bundles.php
StingerSoft\AggridBundle\StingerSoftAggridBundle::class => ['all' => true],
php bin/console assets:install --symlink public/

The bundle ships the glue (a JS file plus Twig helpers), not ag-Grid itself. You must load ag-grid-community (matching the era of the bundle — roughly v22–v24) from CDN or npm in your layout, plus its CSS, before the bundle's glue script.

Where to look first, in order:

  • src/Grid/ — Grid, GridBuilder, GridFactory, GridBuilderInterface. This is the Symfony-Form-style API and the whole mental model.
  • src/Grid/Column/Type/ — TextColumnType, NumberColumnType, DateColumnType, BooleanColumnType, EntityColumnType. These map to ag-Grid colDef entries.
  • src/Data/ (or DataProvider/) — ArrayDataProvider and the Doctrine/ORM provider.
  • src/Twig/ — the extension that renders the container div plus the JSON config script.

First use case — replicate a controller listing. Build one grid class, render it in one template, confirm the JSON in the page source matches what ag-Grid expects. Then wire filtering and sorting. That loop (edit grid class → reload → inspect JSON → look at devtools network/console) is the entire day-to-day workflow.

// src/Grid/ProductGrid.php
class ProductGrid implements GridBuilderInterface
{
    public function buildGrid(GridBuilder $builder, array $options = []): void
    {
        $builder
            ->addColumn('name', TextColumnType::class, [
                'label'    => 'Name',
                'sortable' => true,
                'filter'   => true,
            ])
            ->addColumn('price', NumberColumnType::class, ['label' => 'Price'])
            ->addColumn('createdAt', DateColumnType::class, ['format' => 'Y-m-d'])
            ->setData($this->repository->findAll());   // verify exact method on GridBuilder
    }
}
// Controller
$grid = $this->gridFactory->create(ProductGrid::class);

return $this->render('product/index.html.twig', ['grid' => $grid]);
{# templates/product/index.html.twig #}
{{ aggrid(grid) }}

Verify the exact Twig function and GridBuilder method names against the repo — the package is small enough to read end-to-end in under an hour, and you will need to, because there is essentially no documentation and the README is a stub.

Implementation Patterns

One GridBuilder class per listing (the FormType pattern). This is the bundle's core idea and its best one. A ProductGrid class owns column definitions and data retrieval; controllers stay thin and grids are reusable across admin pages, exports, and tests. Mirror this in Laravel with an abstract Grid class plus a GridFactory resolved from the container.

$builder
    ->addColumn('id',        NumberColumnType::class, ['sortable' => true])
    ->addColumn('name',      TextColumnType::class,   ['sortable' => true, 'filter' => 'agTextColumnFilter'])
    ->addColumn('category',  EntityColumnType::class, [
        'field'      => 'category.name',      // dotted path into the relation
        'label'      => 'Category',
        'route'      => 'category_show',      // for clickable cell renderer, if supported
    ])
    ->addColumn('actions',   TextColumnType::class,   ['sortable' => false, 'filter' => false]);

Column type classes as thin wrappers over colDef. Each type class merges defaults (type, filter, sortable, cellRenderer, formatter) and then applies your options verbatim. Practically, this means any ag-Grid colDef key you know from the JS docs is usually passable through the options array — the bundle is a serializer, not a schema validator. That is both the flexibility and the footgun.

Data providers are the integration seam. ArrayDataProvider is fine for fixtures, small lookups, and report pages. For Doctrine you get an entity provider that returns managed entities; the bundle then serializes them. Two patterns that matter:

  • Pre-shape the data before handing it to the grid. Doctrine entities with DateTime fields, proxies, and circular relations serialize badly. Map to plain arrays with already-formatted strings before setData(). Do not rely on the serializer to do date formatting for you.
  • Use the provider as the place you would put a query object. In Laravel terms, think of it as a GridData action or a repository call returning a Collection — the grid should not own query logic.

Client-side vs server-side row model — the decision that determines whether this bundle is viable. The bundle generates a JSON config plus the full dataset and lets ag-Grid do client-side sorting/filtering/paging. That is perfectly fine up to a few thousand rows. Beyond that you need ag-Grid's Infinite Row Model or Server-Side Row Model, and this bundle does not provide the AJAX endpoint for that — you would hand-roll it, at which point the bundle is giving you column definitions and little else. For a Laravel port, this is also the natural place to diverge: build the grid as a config object and expose GET /grid/{name} returning {rows, total} with startRow/endRow handling.

Twig/Blade rendering as a one-liner. The extension emits something like:

<div id="grid_abc123" class="aggrid" style="height:600px"></div>
<script type="application/json" id="grid_abc123_config">{...}</script>
<script>window.__aggrid_init('grid_abc123');</script>

The practical integration tip: treat that embedded JSON as the contract. Whenever a column renders wrong, dump the JSON first. It tells you instantly whether the bug is server-side (missing/wrong colDef) or client-side (ag-Grid version mismatch, missing module registration).

Reuse across listing + export. Once the column set lives in one class, the same definitions can drive a CSV export (iterate columns, pull fields) and a detail page. This is the second-best argument for adopting the pattern even if you never install the bundle.

Frontend glue. Load ag-Grid before the bundle asset, set the container height explicitly (ag-Grid renders zero-height otherwise), and bind any custom valueFormatter / cellRenderer as named global functions so the JSON config can reference them by string — closures cannot cross the JSON boundary.

Gotchas and Tips

  • Package health is the headline gotcha. 2 stars, 0 dependents, last release September 2020, and no commits since. Treat it as reference source, not a dependency. Vendor/fork it or don't use it.
  • Symfony-version ceiling. A 2020 bundle targets Symfony 4.4/5.x. Expect friction on Symfony 6/7: deprecated ContainerAwareInterface, missing return types on buildGrid, TreeBuilder typing changes. If you must run it, pin Symfony 5.4.
  • Asset install is mandatory and easy to forget. Without assets:install --symlink public/, the glue script 404s and grids silently render as empty divs with a console error you may miss if you filter the network tab.
  • ag-Grid version drift will break it. The bundle predates ag-Grid's module registration (ModuleRegistry.registerModules) and the v31 Theming API. Pair it with an old ag-grid-community (v22–v24), or the init call will throw on removed theme classes. Pin the CDN/npm version explicitly.
  • No enterprise features. Row grouping, pivoting, master/detail, and SSRM are ag-Grid Enterprise features behind a license. The bundle exposes column options, not licensing. Do not promise grouping in an estimate before checking what ag-Grid Community actually supports in your chosen version.
  • Full dataset is serialized into the page. This is the performance cliff. 50k rows means megabytes of HTML and a slow server response before ag-Grid even starts. If your listing can grow, design for SSRM from day one — which, as noted, means writing the endpoint yourself.
  • Closures don't survive json_encode. Any valueFormatter, cellRenderer, or filterParams containing a PHP closure will serialize to null or {}. Use ag-Grid's built-in string expressions, or reference global JS functions by name.
  • Dates and Doctrine entities. DateTime becomes a verbose ISO string or a serialization error depending on the serializer; proxies can pull the entire relation graph. Always normalize to scalars in the data provider.
  • XSS via the embedded JSON. Data containing </script> breaks out of the tag. Ensure the bundle (or your own renderer, in a Laravel port) encodes with JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT, or emits into <script type="application/json"> and parses with JSON.parse(textContent).
  • Debugging checklist, in order: (1) view source, find the config JSON, confirm columnDefs and rowData; (2) confirm the glue script loaded (Network tab, 200 not 404); (3) confirm ag-Grid loaded and agGrid is a global; (4) confirm container has non-zero height; (5) only then look at PHP.
  • Extension points worth knowing for a port: a custom ColumnType (subclass the text/number type and override configureOptions) and a custom DataProvider. Both are small interfaces — reimplementing them in Laravel (Column, ColumnType, DataProvider contracts plus a GridFactory) is a day's work and removes the Symfony coupling entirely.
  • Config quirks. The bundle config tree is minimal (paths/theme-ish settings). Do not expect a rich config surface; anything not exposed as a builder option has to be patched or handled in JS after init via gridOptions.
  • Tests. There is no meaningful test suite to lean on. When you fork, add a single assertion test: given a GridBuilder with N columns, the rendered JSON contains N colDef entries with the expected field/type — that catches 80% of regressions from ag-Grid upgrades.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons