# Using LocalCan with Laravel Herd sites

###### A guide to configure Local Domains and Public URLs for Laravel 11+ development with Herd

This guide shows you how to configure LocalCan to work with Laravel Herd for sites running on Laravel 11 or newer, including setting up Vite with HMR.

#### Prerequisites

- A Laravel 11+ project.
- Laravel Herd installed.
- LocalCan installed.

### Using Public URLs with Laravel Herd

You can use either your [Custom domain](/docs/public-urls/custom-domains) or a subdomain of `localcan.dev` to point to your Laravel Herd site and enjoy traffic inspection and Basic Auth.

1. **Create domain**

   In LocalCan, create a **Domain with proxy** and set the target server as your site, e.g. `http://myapp.test:80` or `https://myapp.test:443`, or even as `http://127.0.0.1:80` or `https://127.0.0.1:443`, because the host header determines which site to serve.

2. **Create [Public URL](/docs/public-urls/overview)**

3. **Set Host header**

   Click the Public URL and open **Request Headers**. Set the Host header to **Target Server Host**. Or, if you set `127.0.0.1` as the target server, choose **Custom** and type the value manually, e.g. `myapp.test`. Either way, Laravel Herd must see the Host header of your site in order to serve it.

### Using Local Domains with Laravel Herd

Local domains `.local` created in LocalCan let you expose your localhost apps and sites on the entire local network (Wi-Fi, LAN, etc.). This is useful for testing your app on different devices or for sharing your app with others.

#### Step 1: Configure Herd

First, we'll configure Herd to serve your site over HTTPS on a custom port to avoid conflicts with LocalCan.

1.  In Herd, select your project's site (e.g., `example.test`) and make sure it's **secured** (uses HTTPS).
2.  **Quit Herd completely** (from the menu bar icon, not just closing the window).
3.  Open your site's Nginx configuration file. You can find it at: `/Users/<user>/Library/Application Support/Herd/config/valet/Nginx/example.test`.
4.  Find the line `listen 127.0.0.1:443 ssl;` and change the port from `443` to `8443`. The line should look like this:
    ```nginx:example.test
    listen 127.0.0.1:8443 ssl;
    ```
5.  Save the file and launch Herd again. Your site should now be accessible at `https://example.test:8443`.

> [!TIP/Alternative setup]
> It's also possible to set your Herd site as HTTP-only (unsecured) and use LocalCan HTTPS proxy, while turning off its HTTP proxy. In this scenario editing Nginx config is not needed.

#### Step 2: Configure LocalCan

Next, we'll set up two local domains in LocalCan: one for your Laravel application and one for the Vite development server.

1.  Make sure LocalCan's **HTTPS proxy is enabled** in the sidebar (the toggle should be green).

2.  **Create a domain for your application:**

    - **Domain:** `https://example.local`
    - **Target Server:** `https://127.0.0.1:8443`
    - Click the domain, open **Request Headers**, and set **Host header** to **Custom**. Enter your Herd site name, e.g., `example.test`. This ensures Herd serves the correct site.

3.  **Create a domain for Vite:**
    - **Domain:** `https://vite.local`
    - **Target Server:** `http://127.0.0.1:5173` (Vite's default address)
    - No need to set the Host header for this one.

After this step, you should have two domains in LocalCan.

#### Step 3: Configure your Laravel project

Now, we need to make some changes to your Laravel project to make it work with our new setup.

1.  **Run the Vite development server:**
    In your project's directory, run `npm run dev`.

2.  **Configure Vite for HMR:**
    Open your `vite.config.js` file and add a `server` configuration block. This tells Vite how to handle HMR requests through LocalCan's proxy.

    ```diff-js:vite.config.js
      // ...
      export default defineConfig({
        // ...
    +   server: {
    +     hmr: {
    +       protocol: 'wss',
    +       host: 'vite.local',
    +       clientPort: 443,
    +     },
    +     cors: {
    +       origin: true,
    +     },
    +   },
      })
    ```

    - `hmr`: Configures Vite to use `vite.local` for HMR, using a secure WebSocket (`wss`) connection. `clientPort: 443` is important as the browser connects to LocalCan on the standard HTTPS port.
    - `cors: { origin: true }`: This is crucial. It allows your application at `https://example.local` to connect to the Vite dev server at `https://vite.local`.

3.  **Force HTTPS scheme in Laravel:**
    Because LocalCan handles HTTPS, Laravel needs to be told to generate `https` URLs. Open `app/Providers/AppServiceProvider.php` and add `URL::forceScheme('https');` to the `boot` method.

    ```diff-php:AppServiceProvider.php
      <?php

      namespace App\Providers;

      use Illuminate\Support\ServiceProvider;
    + use Illuminate\Support\Facades\URL;

      class AppServiceProvider extends ServiceProvider
      {
          public function register(): void
          {
              //
          }

          public function boot(): void
          {
    +        URL::forceScheme('https');
          }
      }
    ```

Now, if you visit `https://example.local` in your browser, your site should load with Vite HMR working correctly.

#### Additional steps

- **Access your `.local` site on iPhone or iPad**

  Follow the guide: [Trust LocalCan Root Certificate on iPhone or iPad](/docs/guides/install-localcan-root-certificate-on-iphone)

- **Avoid hardcoding domain in the code**

  If you your app uses `<site-name>.test` address somewhere in its source code, you may need to replace it with the `<site-name>.local` domain or use relative paths, so that domain is not hardcoded.

