Open Modal based on URL

I’m trying to be able to share a link including a modal with the product defined by the url. I’m using the modal provided by Jetstream.

I’m using livewire 2, laravel 8. AlpineJs 2.8.

I call the modal within the blade view and everything works well, my problem is that I can’t share the link to a specific product. This is the component I call inside a forelse that shows thumbnails of the products and opens the modal with products details:

<x-front.product-listed name="{{ $product->name }}" wire:click='showModal( {{ $product->id }} )' :key="'product-listed-'.$product->id" :key="$product->id" />

I’ve defined the following:

protected $queryString = [
    'product'=>['except'=>''],
];

The blade component included in the view is:
<x-modal.product wire:model.defer="showEditModal" class="relative">...</x-modal>

The function that I use to populate the modal is called showModal:

public function showModal($product_id)
    {
        $showing = Product::find($product_id);
        $this->product=$showing->id; // here I update the url to be able to share the direct link
        $this->name = $showing->name;
        $this->description = $showing->description;
        $this->showEditModal = true;
    }

I’ve added this listeners to the Controller:

protected $listeners = ['showModal'];

I don’t understand how to fire the function that opens the modal (showModal) with the proper product.
I’ve tried this with init and emit:

@if ($product)
<script>
   Livewire.init('showModal',$product);
</script>
@endif

Of course, this doesn’t work.
I can’t wrap my head around this and may be I’m confusing the concepts. I’m a newbie with Livewire and Laravel in general. I’ve tried many things but probably some of them are totally misconceptions because I’m note native english speaker. Can you help me, please? Thanks!

where is this and what’s it for?

Are you using a livewire component to list the products?
Can you share that component?
You mentioned a controller, laravel controllers and livewire components are similar but you can’t necessarily do livewire stuff from a controller…so maybe just verbiage but show your full controller/component

The queryString is in the Livewire component.

namespace App\Http\Livewire;

use App\Models\Product;
use Livewire\Component;
use Livewire\WithPagination;
use Illuminate\Database\Eloquent\Builder;
class Products extends Component
  {
protected $queryString = [ 'producto'=>['except'=>'']];
public $producto = '';
public $showEditModal = false;
public $description = '';
public Product $showing;

public function mount($producto='')
{
    $this->fill(request()->only('producto'));
}

protected $listeners = ['showModal'];

public function showModal($product_id)
{
    $this->dispatchBrowserEvent('modalisopen');
    $this->images = [];
    $showing = Product::find($product_id);
    $this->description = $showing->description;
    $this->showEditModal = true;
}
public function render()
    {
    return view('livewire.products',[ 'products'=>Product::all() ])->layout('layouts.frontpage');
     }
}

The entire view is loaded via livewire and is like this:

    <div class="lg:container mx-auto flex">
        <div class="md:order-2 w-full md:w-3/4 p-4 md:p-0">
            <div wire:loading.class='opacity-50' class="grid grid-cols-2 gap-4 md:grid-cols-3 products-list ">
                @forelse ($products as $product)
                <x-front.product-listed  name="{{ $product->name }}"  wire:click='showModal( {{ $product->id }} )'  :key="'product-listed-'.$product->id"  />
                @empty
                <div class="col-span-2 md:col-span-3"> Nothing here </div>
                @endforelse
            </div><!-- products-list -->
            <div class="mt-8 w-full">{{ $products->links() }}</div>
        </div>
    </div><!-- container -->
    <x-modal.product wire:model.defer="showEditModal">
        <x-slot name="title">{{ $texto }}</x-slot>
        <x-slot name="description">
            {{ $description }}
        </x-slot>
    </x-modal.product>
</div>
namespace App\Http\Livewire;

use App\Models\Product;
use Livewire\Component;
use Livewire\WithPagination;
use Illuminate\Database\Eloquent\Builder;


class Products extends Component
{

  public $producto = '';
  public $showEditModal = false;
  public $description = '';
  public $texto = '';
  public Product $showing;

public function mount()
{
    //$this->fill(request()->only('producto'));
    // ?????????????????
    // idk what this is, commented out and removed the parameter 
}


public function showModal(Product $product)
{
    //NOTE THE MODEL INSTANCE IS TYPEHITTEN IN THE METHOD
    //tells laravel how to find it
    
    //$this->images = [];
    //no images variable declared above
    
    $this->showing = $product;
    // this will call the entire product model
    // and makes it accessible in blade with {{ $showing }}
    
    $this->description = $product->description;
    // in blade you can simply call this with {{ $showing->description }}
    
    $this->texto = $product->title;
    // ??
    // you didn't have this variable declared but its being called in the modal
    // easier to just call {{ $showing->title }} in blade, minimize variables
    
    $this->showEditModal = true;
}

public function render()
{
    return view('livewire.products',[
        'products'=> Product::all(),
    ])
    ->layout('layouts.frontpage');
 }
}