Back to articles

Build a Full-Stack App with React, SvelteKit, and a Serverless Laravel Backend

AuthorMajd Muhtaseb06/17/202515 minutes
Build a Full-Stack App with React, SvelteKit, and a Serverless Laravel Backend

Introduction

This article outlines how to build a modern full-stack application by combining the strengths of React for the frontend, SvelteKit for routing and build tooling, and a serverless Laravel backend for API endpoints. This approach allows for performant frontends, a smooth developer experience, and cost-effective backend infrastructure.

Project Setup

First, let's scaffold a new SvelteKit project:

npm create svelte@latest my-app
cd my-app
npm install

This will be our frontend. Now let's move to the backend.

Laravel Backend (Serverless)

We'll create a basic Laravel API endpoint, configured to be deployable in a serverless environment (like AWS Lambda or Vapor). For brevity, assume you have a Laravel project configured for serverless deployment.

Create a simple controller:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ExampleController extends Controller
{
    public function index()
    {
        return response()->json(['message' => 'Hello from Laravel!']);
    }
}

Define a route in routes/api.php:

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ExampleController;

Route::get('/hello', [ExampleController::class, 'index']);

Remember to configure your Laravel project for serverless deployment. Services like Laravel Vapor provide excellent tools for this.

React Component in SvelteKit

Now, let's create a React component within our SvelteKit project to fetch data from our Laravel API.

First install React and ReactDOM as dev dependencies:

npm install react react-dom --save-dev

Create a file src/lib/ReactComponent.jsx:

import React, { useState, useEffect } from 'react';

function ReactComponent() {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('/api/hello'); // Proxy through SvelteKit
        const data = await response.json();
        setMessage(data.message);
      } catch (error) {
        setMessage('Error fetching data.');
      }
    };

    fetchData();
  }, []);

  return (
    <div>
      <p>Message from Laravel: {message}</p>
    </div>
  );
}

export default ReactComponent;

SvelteKit API Endpoint (Proxy)

Create a SvelteKit API endpoint to proxy the request to your Laravel backend. This avoids CORS issues and allows you to manage API keys securely. Create src/routes/api/hello/+server.js:

import { json } from '@sveltejs/kit';

/** @type {import('./$types').RequestHandler} */
export async function GET() {
  const backendUrl = 'YOUR_LARAVEL_BACKEND_URL'; // Replace with your Laravel URL
  try {
    const response = await fetch(backendUrl + '/api/hello');
    const data = await response.json();
    return json(data);
  } catch (error) {
    return json({ message: 'Error proxying request.' }, { status: 500 });
  }
}

IMPORTANT: Replace YOUR_LARAVEL_BACKEND_URL with the actual URL of your deployed Laravel API.

Displaying the React Component in Svelte

Finally, let's display the React component in a Svelte page. Modify src/routes/+page.svelte:

<script>
  import ReactComponent from '$lib/ReactComponent.jsx';
  import { onMount } from 'svelte';
  import { render } from 'react-dom/client';

  let container;

  onMount(() => {
    container = document.getElementById('react-container');
		const root = render(<ReactComponent/>, container);

  });
</script>

<h1>Welcome to SvelteKit</h1>

<div id="react-container" />

Conclusion

This example demonstrates a powerful stack for building modern web applications. By leveraging React's component model within SvelteKit's routing and build system, and connecting it to a serverless Laravel backend, you can create scalable and maintainable applications with excellent performance. Remember to handle error states and secure your API endpoints in a production environment.