In the previous topic, we explored JavaScript-only third-party Stimulus controllers. Now, we'll learn how to create server-backed Stimulus components.
We'll use Symfony UX Autocomplete and use the demo project as example.
1. Install Symfony UX Autocomplete
(Assume you have already installed and set up the recipes for symfony/asset-mapper and symfony/stimulus-bundle.)
Open the demo project, click Tools -> Composer packages, add the package symfony/ux-autocomplete.
Generate scripts, then install the recipe:
php bin/console app:recipes:install symfony/ux-autocomplete
What the recipe does:
- Adds
assets/controllers.jsonif missing. - Creates or updates
assets/controllers/folder for your Stimulus controllers.
No backend code is generated — the recipe only prepares the frontend and Stimulus integration.
2. Create an Autocompleter Service Using Attributes
Create a Custom File with:
- File Name -
ProductAutocompleter.php - Include Common Files - DISABLE IT. It is not applicable.
- Caption - NOT applicable.
- Path - Set the path as
src/Service. - Content - Enter your whole class, note that you should use the special placeholder
{ProjectNamespace}as your namespace.
Example: ProductAutocompleter
<?php
namespace {ProjectNamespace}\Service;
use {ProjectNamespace}\Db\Entity\Product;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Symfony\UX\Autocomplete\EntityAutocompleterInterface;
#[AutoconfigureTag('ux.entity_autocompleter', ['alias' => 'product'])]
class ProductAutocompleter implements EntityAutocompleterInterface
{
public function getEntityClass(): string
{
return Product::class;
}
public function createFilteredQueryBuilder(
EntityRepository $repository,
string $query
): QueryBuilder {
return $repository->createQueryBuilder('p')
->where('p.productName LIKE :query')
->setParameter('query', '%' . $query . '%')
->orderBy('p.productName', 'ASC')
->setMaxResults(20);
}
public function getLabel(object $entity): string
{
return $entity->getProductName();
}
public function getValue(object $entity): mixed
{
return $entity->getProductId();
}
public function isGranted(Security $security): bool
{
return true;
}
}
Key Points:
- The attribute
#[AutoconfigureTag('ux.entity_autocompleter', ['alias' => 'product'])]registers this service as an entity autocompleter with aliasproduct. - This exposes the autocompleter via the route:
/autocomplete/product.
3. Add a Stimulus Controller
Symfony UX Autocomplete includes a ready-to-use Stimulus controller: symfony/ux-autocomplete/autocomplete.
We can use it in any HTML page, e.g.
<label for="product-input">Choose a product:</label>
<input type="text"
id="product-input"
{{ stimulus_controller('symfony/ux-autocomplete/autocomplete', {
url: path('ux_entity_autocomplete', { alias: 'product' }),
min_characters: 1
}) }}
placeholder="Type a product name...">
In addition to min_characters, you can also pass other options such as max_results to control the backend query:
4. How It Works
- User types in the input.
- Stimulus controller sends an AJAX request to
/autocomplete/product?query=<input>. - The
ProductAutocompletersearches the database and returns results. - Suggestions are displayed under the input.
- Selecting a suggestion fills the input with the value.
No custom JavaSript is required — everything works out of the box.