neo/laravel-early-access
Neo Laravel Early Access is a lightweight Laravel package for adding waitlists and invite-only registration to your app. Collect early-access signups, manage invitations, and gate features with middleware and Eloquent models until public launch.
composer require neo/laravel-early-access. Laravel 5.5+ auto-discovers the service provider; on older apps register Neo\EarlyAccess\EarlyAccessServiceProvider manually in config/app.php.php artisan vendor:publish --provider="Neo\EarlyAccess\EarlyAccessServiceProvider"
This drops a config file (typically config/early-access.php) and a Blade view for the screen itself..env — usually a single boolean (EARLY_ACCESS_ENABLED=true). The package is meant to be flipped on only in staging/production, so keep it false locally.app/Http/Kernel.php or the provider source before assuming your routes are still reachable./ — you should see the published early access view instead of your app. First real use case: standing up a pre-launch marketing page with an email capture form without building a separate app.Global gate with a bypass for the team. The canonical pattern is: middleware intercepts requests, checks a bypass condition (secret query string, cookie, allowlisted IP, or auth session), and either renders the early access view or passes the request through. The team shares a /secret-xxx link, which sets a long-lived cookie, after which the normal app loads. Use this for internal QA against the real app while the public sees the gate.
Route-group scoping instead of global. If the provider registers globally, move the middleware into the web group or apply it only to the routes you want gated. This is the practical fix for keeping /api/*, /webhooks/*, health checks, and Nova/Stripe webhooks alive. Without this, you’ll silently break integrations the day you flip the flag.
Email capture pipeline. Replace the stub form action with your own EarlyAccessSignupController@store (or a Mailchimp/ConvertKit/Buttondown call) and redirect back with a flash message. Persist to a signups table if you want to own the list. This is the package’s real value — the screen is 90% of the design work done for you.
Environment-scoped rollout. Drive the flag from APP_ENV so staging is gated (public-ish) and local is not. Typical .env:
EARLY_ACCESS_ENABLED=true
paired with config('early-access.enabled') in your provider/feature-flag logic. Treat it as the bluntest possible feature flag — it’s app-wide on/off.
Branding pass. Publish the view, then swap the copy, logo, fonts, and CTA. Because it’s plain Blade with no JS framework dependency, it drops cleanly into any Tailwind/Bootstrap project. Keep your edits in resources/views/vendor/laravel-early-access/ so future re-publishes don’t clobber them.
Combine with auth-aware bypass. For a customer-only beta, if (auth()->check() && auth()->user()->is_beta_tester()) { return $next($request); } in a thin wrapper middleware lets invited users through while everyone else sees the gate. This is a two-line extension of the package’s model.
/api routes, asset requests, and even the Laravel error page can be swallowed. Add $except entries or scope to the web group..env or the config, run php artisan config:clear (or config:cache). A stale cache is the #1 reason “it didn’t turn on.”php artisan view:clear when you change the published Blade view — otherwise you’ll debug a page that isn’t what’s rendering.?secret= bypass lands in proxy logs, analytics, and Referer headers. Prefer a POST form that sets the cookie, and consider expiring the cookie.VerifyCsrfToken middleware still applies — 419s on the early access page are a common first-day bug.<env name="EARLY_ACCESS_ENABLED" value="false"/> to phpunit.xml (or your TestCase), or every feature test will hit the gate and assert against the marketing page instead of your app.How can I help you explore Laravel packages today?