Query String

Updating the browser's query string when a component state change is supported and easy to implement.

E.g: When implementing an "Articles" component with a text input to search by keywords you would expect the URL to change as https://my-app.com/articles?search=mySearchString

This way, when a user hits the back button, or bookmarks the page, you can get the initial state out of the query string, rather than resetting the component every time.

To achieve this, you should add a property's name of your component to protected $queryString. The query string will update every time the property value changes, and the property value will update when the query string changes.

use Drupal\wire\View;
use Drupal\wire\WireComponent;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;

/**
 * Implementation for Articles Wire Component.
 *
 * @WireComponent(
 *   id = "articles",
 *   label = @Translation("Articles"),
 * )
 */
class Articles extends WireComponent {

  public string $search = '';

  protected array $queryString = ['search'];

  protected ?EntityTypeManagerInterface $entityTypeManager;

  public static function create(
    ContainerInterface $container,
    array              $configuration,
                       $plugin_id,
                       $plugin_definition
  ) {
    $instance = new static($configuration, $plugin_id, $plugin_definition);
    $instance->entityTypeManager = $container->get('entity_type.manager');
    return $instance;
  }

  public function render(): ?View {

    $nodeStorage = $this->entityTypeManager->getStorage('node');
    $nodeQuery = $nodeStorage->getQuery()->accessCheck(TRUE);
    $nodeQuery->condition('type', 'article')
      ->condition('status', 1)
      ->condition('title', '%' . addcslashes($this->search, '\%_') . '%', 'LIKE');

    $articleEntities = $nodeStorage->loadMultiple($nodeQuery->execute());

    return View::fromTpl('articles', [
      'items' => array_map(function ($article) {
        return $article->label();
      }, $articleEntities),
    ]);
  }

}
<div>

  <input wire:model="search" type="search" placeholder="Search article by title...">

  <h1>Articles</h1>

  <ul>

    {% for item in items %}

      <li>{{ item }}</li>

    {% endfor %}

  </ul>

</div>

In the case above, when the search property is empty, the query string will look as ?search=

It is possible to only manipulate the query string if it is NOT the default value.

Use except keyword as shown bellow.

class Articles extends WireComponent {

  public string $dummy = '';
  
  public string $search = '';
  
  public int $page = 0;
  
  protected array $queryString = [
    'dummy',
    'search' => ['except' => ''],
    'page' => ['except' => 0],
  ];
  
  ...

Note additional example provided for pagination via $page public property which would be used to not track the first page.

It is possible to modify how properties are represented in the URL.

For example, if you want to shorten the URL, where the page property is represented as p and search as s, you can use the as modifier to achieve that outcome.

class Articles extends WireComponent {

  public string $search = '';

  public int $page = 1;

  protected array $queryString = [
    'search' => ['except' => '', 'as' => 's'],
    'page' => ['except' => 1, 'as' => 'p'],
  ];
  
  ...

 

********************************** ************************* ************************ **************** ****************** *********** ************** ************* ************ *************

© Wire Drupal

Build with Luna