DEV Community

Cover image for Deploying a Laravel API + Separate Frontend (Next.js, Nuxt, SPA) on Deploynix
Deploynix
Deploynix

Posted on • Originally published at deploynix.io

Deploying a Laravel API + Separate Frontend (Next.js, Nuxt, SPA) on Deploynix

The days of Laravel serving Blade templates for every page are not over, but they are no longer the only option. More teams are choosing to build their Laravel backend as a pure API and pair it with a JavaScript frontend framework like Next.js, Nuxt, or a single-page application built with React, Vue, or Svelte. This architecture offers real benefits: specialized frontend tooling, independent deployment cycles, and the ability to serve multiple clients (web, mobile, third-party integrations) from a single API.

But this architecture also introduces deployment complexity that a traditional Laravel application does not have. You now have two applications to deploy, two sets of environment variables to manage, and a network boundary between your frontend and backend that needs careful configuration. CORS headers, authentication tokens, API versioning, and deployment coordination all become first-class concerns.

In this guide, we will walk through exactly how to set up this architecture on Deploynix, covering server topology, site configuration, CORS handling, authentication, and deployment strategies that keep both halves of your application in sync.

Choosing Your Server Topology

The first decision is whether your API and frontend should live on the same server or separate servers. Both approaches work on Deploynix, and the right choice depends on your traffic patterns and scaling needs.

Same Server, Different Sites

For most applications in their early stages, running both the Laravel API and the frontend on the same Deploynix App server is the simplest approach. You create two sites on the same server, each pointing to its own Git repository and domain.

Your Laravel API might live at api.yourapp.com, configured as a standard Laravel site with PHP processing. Your frontend might live at app.yourapp.com, configured to serve static files (for an SPA) or to proxy to a Node.js process (for Next.js or Nuxt with server-side rendering).

This approach has the advantage of minimal network latency between your frontend's server-side rendering layer and your API. If your Next.js application makes server-side API calls during page rendering, those calls travel over localhost rather than across the internet.

Separate Servers

As your application grows, you will likely want to separate these concerns. Your Laravel API goes on an App server (or multiple Web servers behind a Load Balancer), while your frontend goes on its own Web server. This gives you independent scaling: if your API is the bottleneck, add more API servers without touching your frontend infrastructure.

On Deploynix, you can provision these servers on different cloud providers if it makes sense. Your API might run on Hetzner for cost-effective compute, while your frontend runs on a provider with edge locations closer to your users. Deploynix manages SSH connections, provisioning, and deployments across all providers through the same interface.

A dedicated Database server and Cache server round out the infrastructure. Your API connects to these backend services, while your frontend server only needs to communicate with the API (and possibly a CDN for static assets).

Setting Up the Laravel API

Your Laravel API configuration on Deploynix follows the standard Laravel site setup with a few specific considerations.

API-Focused Environment Configuration

Your .env file should reflect that this application is an API. Set SESSION_DRIVER appropriately based on your authentication strategy. If you are using Laravel Sanctum for token-based authentication (which Deploynix itself uses), you may not need sessions at all for API-only requests. If you are using Sanctum's SPA authentication mode with cookies, you will need session support.

Set your SANCTUM_STATEFUL_DOMAINS to include your frontend's domain. This tells Sanctum to treat requests from your frontend as first-party and use cookie-based authentication when appropriate:

SANCTUM_STATEFUL_DOMAINS=app.yourapp.com,localhost:3000
Enter fullscreen mode Exit fullscreen mode

Including localhost:3000 allows your frontend developers to authenticate against the production or staging API during local development.

CORS Configuration

Cross-Origin Resource Sharing is the mechanism that allows your frontend on app.yourapp.com to make API requests to api.yourapp.com. Laravel includes CORS middleware out of the box, and getting it right is critical.

In your config/cors.php file, configure the allowed origins to include your frontend domain. Do not use a wildcard *) in production, it is both a security risk and incompatible with credentialed requests:

'allowed_origins' => [
    'https://app.yourapp.com',
],
'allowed_methods' => ['*'],
'allowed_headers' => ['*'],
'supports_credentials' => true,
Enter fullscreen mode Exit fullscreen mode

The supports_credentials setting is essential if you are using Sanctum's cookie-based SPA authentication. It tells the browser that it is safe to include cookies in cross-origin requests.

API Versioning

When your API serves a separate frontend, versioning becomes important. Your frontend and API deploy on independent schedules, so you need a way to evolve your API without breaking the currently deployed frontend.

Prefix your API routes with a version number. Use Laravel's route groups to keep this clean:

Route::prefix('v1')->group(function () {
    Route::apiResource('projects', ProjectController::class);
    Route::apiResource('deployments', DeploymentController::class);
});
Enter fullscreen mode Exit fullscreen mode

Use Eloquent API Resources to control the shape of your responses. Resources give you a stable output format that is independent of your model structure, so internal refactoring does not break your API contract.

Rate Limiting and Throttling

With a public-facing API, rate limiting is non-negotiable. Laravel's built-in rate limiting middleware protects your API from abuse and ensures fair resource distribution. Configure different limits for authenticated and unauthenticated requests.

Deploynix's monitoring and health alerts will notify you if your API server's resources are being consumed faster than expected, which can indicate either legitimate growth or an attack that your rate limiting is not catching.

Setting Up the Frontend

Your frontend deployment on Deploynix depends on the type of frontend application you are building.

Static SPA (React, Vue, Svelte)

If your frontend is a single-page application that builds to static HTML, CSS, and JavaScript files, the deployment is straightforward. Create a site on Deploynix pointing to your frontend repository. Configure the web directory to point to your build output folder (typically dist or build).

In your site's deploy script, add the build commands that run during each deployment:

npm ci
npm run build
Enter fullscreen mode Exit fullscreen mode

Deploynix executes your deploy script during deployment, building your frontend on the server. You can also enable auto-deploy through Deploynix's git integration, so every push to your configured branch triggers a deployment automatically via webhooks. The Nginx configuration serves the static files directly, with a fallback rule that routes all paths to index.html for client-side routing.

Server-Rendered (Next.js, Nuxt)

Server-rendered frontends are more involved because they run a persistent Node.js process. On Deploynix, you configure this using a daemon that keeps your Node.js server running.

After deploying your Next.js or Nuxt application, set up a daemon through Deploynix that runs:

npm start
Enter fullscreen mode Exit fullscreen mode

Configure Nginx as a reverse proxy that forwards requests to the Node.js process. This gives you the benefits of Nginx's static file serving and SSL termination while letting Node.js handle the server-rendered pages.

Your site's deploy script should include the build step:

npm ci
npm run build
Enter fullscreen mode Exit fullscreen mode

After the build completes, Deploynix can restart the daemon to pick up the new build.

Authentication Strategies

The authentication approach you choose affects both your deployment configuration and your frontend code.

Sanctum Token Authentication

For mobile apps, third-party integrations, or frontends that do not share a domain with the API, token-based authentication is the cleanest approach. Your frontend sends a login request to the API, receives a token, and includes that token in the Authorization header of subsequent requests.

This approach requires no special CORS configuration for credentials, no cookie handling, and no session management on the API side. It works across any domain boundary and is the approach Deploynix uses for its own API with granular token scopes.

Sanctum SPA Authentication

For first-party web frontends, Sanctum's SPA authentication uses cookies and sessions to provide a seamless authentication experience. The flow starts with a request to /sanctum/csrf-cookie to establish a CSRF token, followed by a login request that sets an authentication cookie.

This approach requires more careful configuration. Your SANCTUM_STATEFUL_DOMAINS must be correct. Your CORS configuration must support credentials. And your frontend must be configured to send credentials with every request.

The advantage is a more traditional authentication model that handles CSRF protection, session expiration, and cookie security automatically.

Deployment Coordination

With two independent applications, deployment coordination becomes a real concern. If your API deploys a breaking change before your frontend updates to handle it, users will see errors.

Strategy 1: API Backward Compatibility

The safest approach is ensuring your API is always backward compatible. Never remove or rename a field in an API response. Never change the validation rules for an existing endpoint in a way that rejects previously valid input. Use API versioning to introduce breaking changes under a new prefix.

With this approach, deployment order does not matter. Your API can deploy at 2 PM and your frontend at 4 PM, and nothing breaks in between.

Strategy 2: Coordinated Deployments with Deploynix

If you need to deploy coordinated changes, Deploynix's scheduled deployment feature lets you queue deployments for both your API and frontend sites at the same time. Schedule both deployments for the same minute, with the API deploying first.

Deploynix's zero-downtime deployment ensures that your API switches over atomically. The old version continues serving requests until the new version is fully ready. Your frontend deployment follows seconds later, and the brief window where the new frontend talks to the old API is handled by the backward compatibility of your API versioning.

Strategy 3: Feature Flags

For complex changes that span both applications, feature flags let you deploy code to both sides without activating it. Deploy the API changes behind a feature flag. Deploy the frontend changes that check for the flag. Then flip the flag to activate both simultaneously, regardless of when each side was deployed.

Shared Resources and Environment Variables

Both your API and frontend need to agree on certain values. Your frontend needs to know the API URL. Your API needs to know the frontend URL (for CORS, email links, and redirects). Keep these in environment variables on both sides.

On Deploynix, each site has its own environment variable management. Set API_URL=https://api.yourapp.com on your frontend and FRONTEND_URL=https://app.yourapp.com on your API. This keeps the coupling explicit and configurable.

For shared secrets like encryption keys or webhook signing secrets, use the same value in both applications' environment configurations. Deploynix stores environment variables securely and makes them available to your application during deployment and runtime.

SSL and Domain Configuration

Both your API and frontend need SSL certificates. Deploynix handles SSL auto-provisioning for both sites, whether they are on the same server or different servers. If you are using subdomains api.yourapp.com and app.yourapp.com), both certificates are provisioned independently.

For development and staging environments, Deploynix's vanity domain feature gives you *.deploynix.cloud subdomains with automatic SSL. Your staging API might be at my-api.deploynix.cloud and your staging frontend at my-app.deploynix.cloud, both with valid certificates and no DNS configuration required.

Deploynix supports DNS providers including Cloudflare, DigitalOcean, AWS Route 53, and Vultr for DNS-based SSL challenges, which is particularly useful for wildcard certificates.

Monitoring Both Halves

With two applications to monitor, Deploynix's real-time monitoring and health alert system becomes doubly important. Set up health checks for both your API and frontend sites. Monitor response times on your API to catch performance regressions before your users do.

Your API's health check should verify database connectivity, cache availability, and queue processing. Your frontend's health check should verify that the application loads and that it can reach the API.

Configure Deploynix's alert system to notify you when either side degrades. A frontend that cannot reach its API is just as broken as an API that is down, and you need to know about both.

Conclusion

Deploying a Laravel API with a separate frontend is a legitimate architectural choice that Deploynix fully supports. The key is treating both applications as first-class citizens in your infrastructure, giving each its own deployment pipeline, monitoring, and scaling strategy.

Start with both applications on a single server to keep things simple. As your traffic grows, separate them onto dedicated servers with a shared Database and Cache server. Use Deploynix's Load Balancer to scale whichever side needs more capacity.

Get your CORS and authentication configuration right from the start. Use API versioning to decouple your deployment schedules. And use Deploynix's deploy scripts, auto-deploy webhooks, scheduled deployments, and monitoring to keep both halves of your application healthy and in sync.

The separation of frontend and backend is not inherently more complex than a traditional Laravel application. It is differently complex, and the tools to manage that complexity are available on Deploynix today.

Top comments (0)