Share a Laravel site from your laptop, styles and forms included
php artisan serve shares as it is, but its links, forms and built styles say localhost until trustProxies. Vite's hot file needs a build instead.
Updated
Shared through ouicu, php artisan serve answers the link as it comes, but every address Laravel writes into a page says http://localhost:8000: links, form actions and the styles from your build. One line in bootstrap/app.php makes them the link's. Vite's dev server is the other catch, and the answer there is a build.
| Laravel | |
|---|---|
| Dev server port | 8000 |
| On your Wi-Fi | php artisan serve --host=0.0.0.0 |
| Host check | None as it comes |
Links, forms and styles that say localhost
ouicu hands Laravel Host: localhost:8000, so there's no host to allow: “By default, Laravel will respond to all requests it receives regardless of the content of the HTTP request's Host header.” The same paragraph of the docs gives the catch: “In addition, the Host header's value will be used when generating absolute URLs to your application during a web request.”
So through the link, a new project's welcome page loads, and everything absolute points at your laptop. What we saw, opening each through a ouicu link:
| In the page | What Laravel wrote | For the visitor |
|---|---|---|
url()->current() | http://localhost:8000/where | Their own computer's address |
action="{{ route('echo') }}" | http://localhost:8000/echo | Sending the form leaves the link |
| The stylesheet from npm run build | http://localhost:8000/build/assets/app-….css | The page arrives unstyled |
Redirects are the exception. ouicu turns a redirect to http://localhost:8000 into one to the link, so a form that posts to a path, action="/echo", lands back on the link with its session intact.
| Through the link | What it takes |
|---|---|
| The page | Needs $middleware->trustProxies(at: '*') |
| Hot reload | Doesn't come through; use npm run build instead |
| A form POST | Needs $middleware->trustProxies(at: '*') |
Fix it: trustProxies in bootstrap/app.php
Tell Laravel to believe the proxy's headers. A new project has an empty withMiddleware call in bootstrap/app.php; give it one line:
->withMiddleware(function (Middleware $middleware): void { $middleware->trustProxies(at: '*');})Laravel then reads X-Forwarded-Host and X-Forwarded-Proto, which ouicu sends with every request. url() gives https://calm-otter-4821.ouicu.app/where, the route() form posts to the link and lands back on it, and the built stylesheet loads. The docs describe the same symptom behind any proxy that ends https:
“When running your applications behind a load balancer that terminates TLS / SSL certificates, you may notice your application sometimes does not generate HTTPS links when using the
urlhelper.”
For a proxy whose address you can't know, they say “you may use * to trust all proxies”. On your laptop, ouicu is that proxy. In production, list your own proxies rather than everyone.
419 Page Expired
Laravel answers a form it won't accept with status 419 and a page that says:
Page ExpiredThrough a ouicu link you're unlikely to meet it. Laravel 13.0 changed the check; the upgrade guide says:
“Laravel's CSRF middleware has been renamed from
VerifyCsrfTokentoPreventRequestForgery, and now includes request-origin verification using theSec-Fetch-Siteheader.”
And the CSRF docs: “If the header indicates the request came from the same origin, the request is allowed immediately without any token verification.” A ouicu link is https, so the browser sends that header. In our test, a POST from the page went through with no token at all, and a form with @csrf passed too. A POST without the header and without a token got Page Expired. The docs give the reason it can be missing: “The Sec-Fetch-Site header is only sent by browsers over secure (HTTPS) connections.” So keep @csrf in your forms, for a phone on your Wi-Fi over plain http.
Vite's hot file sends visitors home
npm run dev starts Vite on a port of its own and writes its address to public/hot. Here it held http://[::1]:5173. While that file exists, @vite points every page at it, so through the link the visitor's browser asks its own computer for your styles and scripts. None of them loaded, and hot reload never connected. The link carries one port, and Vite's is a second.
Stop npm run dev, check public/hot is gone, and build:
npm run buildphp artisan serve# in a second terminalouicu share 8000With trustProxies set, the built files load from the link. A Blade edit still shows when the page loads again: we changed the welcome page's heading and it was there on the next load. A change to your CSS or JavaScript needs another build.
Share php artisan serve with ouicu
Start Laravel as usual and share its port in a second terminal. Getting started has the install.
php artisan serve# in a second terminalouicu share 8000Laravel listens on your computer alone, and says so as it starts:
Server running on [http://127.0.0.1:8000].That's all ouicu needs. On Free, a share runs for up to 2 hours. A phone on your Wi-Fi needs php artisan serve --host=0.0.0.0 and your computer's address; the QR code ouicu prints needs neither (QR codes, how to open localhost on your phone).
Herd, and sites on .test names
Laravel Herd has a share command of its own. “Herd uses Expose to share your sites.” “To share your site using Expose, you first need to create a free Expose account.” ouicu shares a port instead, and hands the server Host: localhost with that port. A server that picks the site by its .test name won't find yours that way, and we haven't tested Herd or Valet behind ouicu. Run php artisan serve in the project and share its port.
Debug pages, and who can open the link
A new project's .env has APP_DEBUG=true, so an error shows whoever hit it Laravel's full error page. The docs warn of it in production:
“If the variable is set to
truein production, you risk exposing sensitive configuration values to your application's end users.”
A shared dev server is closer to production than it looks: anyone with the link reaches it. For a client, ask for a password, on Hobby and Pro:
ouicu share 8000 --passwordOr name the people allowed in, on Pro, with --allow. ouicu asks at the door, before Laravel sees the request. The link carries web pages only: a download, a video or a PDF from storage is kept back, as is anything over 50 MB (what isn't passed on).
Why not upload it
Laravel renders each page on the server, and ouicu deploy uploads static files only, so a Laravel site is shared live, from your laptop. To show a client, share it while you walk them through; see show a client a website before it goes live.
Tested with Laravel 13.35.0 on , with PHP 8.5.11: composer create-project laravel/laravel with a Blade form, served by php artisan serve in the official composer Docker image and shared with ouicu share through ouicu's edge: the welcome page, url(), forms with and without a token, npm run dev and npm run build, before and after trustProxies, in Chromium at the https link, whose own localhost went nowhere, as a client's would.
Sources
Prices, defaults and quotes about other products, and the day each was last checked at its source.
- ServeCommand.php, Laravel on GitHub. Checked .
- HTTP Requests: Configuring Trusted Proxies, Laravel docs. Checked .
- Exceptions/views/419.blade.php, Laravel on GitHub. Checked .
- Upgrade Guide: Request Forgery Protection, Laravel docs. Checked .
- CSRF Protection, Laravel docs. Checked .
- laravel/vite-plugin: src/index.ts, Laravel on GitHub. Checked .
- Sharing Sites, Laravel Herd docs. Checked .
- laravel/laravel: .env.example, Laravel on GitHub. Checked .
- Configuration: Debug Mode, Laravel docs. Checked .