Beyond the Chat Interface While 2025 cemented the chat agent as the default AI interface for platforms like Linear and PostHog, the paradigm is shifting toward voice. Voice is inherently more accessible and enables omnichannel interactions that text cannot touch—think automated phone support or agents joining Zoom calls to verify data in real-time. The challenge for developers isn't starting over, but upgrading the sophisticated agents they've already tuned with RAG and complex tool-calling logic. Prerequisites To follow this guide, you should be comfortable with **JavaScript/TypeScript**, understand **RESTful API** patterns, and have an existing chat agent architecture (like a Node.js backend) that processes text strings and returns responses. Key Libraries & Tools * **ElevenLabs Voice Engine**: The core primitive that handles the speech-to-text (STT) and text-to-speech (TTS) pipeline. * **Scribe**: ElevenLabs' high-accuracy STT model used for transcription. * **V3 Turbo**: The low-latency TTS model optimized for conversational speed. * **Shadcn/UI**: Used for the pre-built, accessible frontend components. Implementing the Server Wrapper The beauty of the ElevenLabs approach is that you don't rewrite your agent logic. You wrap it. The server SDK acts as a proxy, intercepting the audio stream, converting it to text for your existing agent, and then synthesizing the agent's response back into high-quality audio. ```javascript import { VoiceEngineClient } from "@elevenlabs/sdk"; const client = new VoiceEngineClient({ apiKey: process.env.ELEVENLABS_API_KEY }); // Wrap your existing chat logic const voiceAgent = client.voiceEngine.create({ agent: async (textInput) => { // This calls your existing LLM/RAG pipeline const response = await myExistingChatAgent.process(textInput); return response.text; }, voiceId: "pMs7msAnqA7ihSps3teH", sttModel: "scribe-v1" }); ``` Frontend Integration and UI On the client side, integration is even leaner. You can use pre-built components styled with Tailwind CSS and Vercel aesthetics to provide visual feedback for voice activity. ```javascript // In your React/Next.js component import { VoiceWidget } from "@elevenlabs/react-ui"; export default function App() { return <VoiceWidget agentId="your-wrapped-agent-id" />; } ``` Syntax Notes and Best Practices The engine uses **Semantic Break Detection**, which understands context-aware pauses. It knows the difference between a user pausing to think and a user finishing their sentence. When implementing tool calling, keep your logic on the server side; the Voice Engine will proxy these calls through your wrapped agent, maintaining the state of your existing backend without requiring a frontend rewrite. Tips & Gotchas Avoid the trap of rebuilding your RAG pipeline inside the voice engine. By using the **Proxy Paradigm**, you retain your existing evals and prompt engineering. If your agent feels slow, check the **TTS model settings**; switching to a "Turbo" variant often reduces the time-to-first-byte for audio playback, which is critical for making AI feel human.
Tailwind CSS
Software
Dec 2020 • 1 videos
High activity month for Tailwind CSS. Laravel among the most active voices, with 1 videos across 1 sources.
Feb 2021 • 1 videos
High activity month for Tailwind CSS. Laravel among the most active voices, with 1 videos across 1 sources.
Dec 2021 • 2 videos
High activity month for Tailwind CSS. Laravel among the most active voices, with 2 videos across 1 sources.
Sep 2024 • 1 videos
High activity month for Tailwind CSS. Laravel among the most active voices, with 1 videos across 1 sources.
Nov 2024 • 1 videos
High activity month for Tailwind CSS. Laravel among the most active voices, with 1 videos across 1 sources.
Sep 2025 • 1 videos
High activity month for Tailwind CSS. Laravel among the most active voices, with 1 videos across 1 sources.
Dec 2025 • 1 videos
High activity month for Tailwind CSS. Laravel among the most active voices, with 1 videos across 1 sources.
Feb 2026 • 1 videos
High activity month for Tailwind CSS. Laravel Daily among the most active voices, with 1 videos across 1 sources.
May 2026 • 1 videos
High activity month for Tailwind CSS. AI Engineer among the most active voices, with 1 videos across 1 sources.
- May 9, 2026
- Feb 18, 2026
- Dec 6, 2025
- Sep 4, 2025
- Nov 7, 2024
Overview of Maintainable Statamic Development Building a website is easy; maintaining it for three years is where the real challenge lies. In the ecosystem of Laravel, Statamic stands out as a unique hybrid CMS—balancing the speed of flat-file storage with the power of a dynamic framework. This guide focuses on building sites that don't just work on launch day but remain easy to update, scale, and support through architectural best practices. By embracing "The Statamic Way," developers can create highly composable interfaces that empower clients while maintaining strict design integrity. We will explore how to use fieldsets for global consistency, implement a robust "Page Builder" using replicator sets, and organize Antlers templates to prevent the dreaded "spaghetti view" folder. Prerequisites To follow this tutorial, you should have a baseline understanding of: - **PHP & Laravel Basics**: Understanding how Laravel structures its directories and handles logic. - **Statamic Fundamentals**: Knowledge of Entries, Collections, and Blueprints. - **Tailwind CSS**: Used for the styling examples in our components. - **Antlers Templating**: Familiarity with the double-curly brace `{{ variable }}` syntax. Key Libraries & Tools - Statamic: A flat-file first CMS built on Laravel. - **Antlers**: The built-in templating engine for Statamic, optimized for CMS data. - **Alpine.js**: For lightweight front-end interactivity. - **Tailwind CSS**: The preferred utility-first CSS framework for Statamic sites. - **Vite**: The build tool used for asset compilation. - **PHPStorm**: The IDE used for the code demonstrations. Code Walkthrough: Composable Components and Page Builders 1. Creating Reusable Metadata with Fieldsets Instead of defining SEO fields for every collection, we use Fieldsets to create a "single source of truth." ```yaml metadata.yaml fieldset configuration title: Metadata fields: - handle: meta_title field: type: text display: Meta Title - handle: meta_description field: type: textarea display: Meta Description - handle: og_image field: type: assets max_files: 1 display: Open Graph Image ``` By linking this fieldset in your **Blueprints**, any change to the metadata structure (like adding a canonical URL field) automatically propagates to both your "Pages" and "Movies" collections. 2. The Button Component with Slots To ensure buttons look consistent across the site while remaining flexible, we use partials with slots. ```antlers {{# views/partials/components/button.antlers.html #}} <a href="{{ href ?? '#' }}" class="px-4 py-2 bg-amber-500 rounded text-white hover:bg-amber-600 transition"> {{ slot }} {{ if icon }} <span class="ml-2">{{ partial:icons/{{ icon }} }}</span> {{ /if }} </a> ``` You can then call this button from any template, passing specific markup into the default slot: ```antlers {{ partial:components/button href="/tickets" }} Buy Tickets Now {{ slot:icon }}ticket{{ /slot:icon }} {{ /partial:components/button }} ``` 3. Implementing the Dynamic Page Builder A maintainable Page Builder avoids huge `if/else` chains in your main layout. Instead, use the `type` variable to dynamically load partials. ```antlers {{# In your layout file #}} <div class="page-builder"> {{ page_builder }} {{ partial src="page_builder/{type}" }} {{ /page_builder }} </div> ``` This pattern looks for files in `views/partials/page_builder/`. If the user adds a "Text" set, Statamic loads `text.antlers.html`. If they add a "Random Movies" set, it loads `random_movies.antlers.html`. This keeps each block's logic isolated and clean. Syntax Notes: Antlers Best Practices - **The Colon Prefix (`:`)**: When passing a variable into a partial, use `{{ partial:name :variable="actual_var" }}`. The colon tells Antlers to treat the string as a variable rather than a literal string. - **Local Variables**: Use a leading underscore (e.g., `_my_var`) for variables that are only relevant within a specific partial. This distinguishes them from global entry data. - **Dry Templates**: Use `{{ yield }}` and `{{ section }}` just like you would in Blade to inject scripts or styles into specific parts of your main layout from a nested template. Practical Examples: The "Salt + G" Stack Modern Statamic development often follows the **SALT+G** acronym: Statamic, Alpine.js, Laravel, Tailwind CSS, plus **Git**. Because Statamic is flat-file, your content exists as YAML and Markdown files. By using the Git Integration, content changes made by a client on production are automatically committed and pushed back to your repository. This allows developers to pull down the production content locally without ever touching a database dump. Reducing the Cost of Action in Development Teams While code quality is vital, Max Brokman argues that the most expensive part of software development isn't the CPU cycles—it's the **Cost of Action**. This is the sum of fear, uncertainty, and frustration that prevents a developer from making progress. Eliminating Decision Fatigue Every choice—from which queue driver to use to where to place a utility class—has a cost. 1. **Don't Fight the Framework**: If you are using Laravel, do things the "Laravel Way." Avoid the temptation to bolt on micro-framework patterns that require ten different documentation sites to understand. 2. **Avoid Resume-Driven Development**: Implementing Kafka for a small blog because it looks good on a resume adds massive maintenance debt. Use the simplest tool that solves the problem "right now." Optimizing the "Joiner" Experience A team's health is often measured by how quickly a new developer can run `git clone` and see the application in their browser. - **Seeders over Dumps**: Never rely on production database dumps for local dev. Maintain robust seeders and factories. - **The "Nuke" Command**: Create a script that deletes all Docker volumes and rebuilds the environment from scratch. If this script fails, your environment is too fragile. - **Document the "Arcane"**: If a specific environment variable is required for a third-party API, it must be in the `.env.example`. Tips & Gotchas - **Premature Abstraction**: Don't build a component for a button if you only have one button on the entire site. Wait until you see the pattern repeat three times. - **The Scaling Myth**: Many developers over-architect for 100 million users when they currently have zero. Use the `sync` or `database` queue driver until you actually hit a performance ceiling. - **Reviewer Fatigue**: In code reviews, automate the nitpicks. Use tools like Laravel Pint to handle formatting so humans can focus on the architectural logic. - **Read the Docs**: Statamic has world-class documentation. Most "custom" solutions developers build are actually already handled by a built-in tag or fieldtype.
Sep 25, 2024Overview Modern web development often requires a clean separation between the data layer and the presentation layer. Connecting Remix to a Laravel REST API allows you to utilize the powerful server-side rendering (SSR) capabilities of React while keeping your business logic within a robust PHP backend. This approach moves authentication logic to the server, enhancing security by keeping sensitive tokens out of the client's reach. Prerequisites To follow this guide, you should have a solid grasp of JavaScript and React. You will also need Node.js installed and a functioning Laravel API. Familiarity with environment variables and HTTP requests is essential. Key Libraries & Tools * **Axios:** A promise-based HTTP client used to perform requests to the API. * **dotenv:** Loads configuration variables from a `.env` file. * **Tailwind CSS:** A utility-first CSS framework for rapid UI development. * **Laravel Sanctum:** Provides the token-based authentication system on the backend. Code Walkthrough Configuring the Server-Side Axios Instance Create `services/axios.server.js` to centralize your API requests. This ensures every request uses the correct base URL and handles errors globally. ```javascript import axios from "axios"; const api = axios.create({ baseURL: process.env.API_HOST, headers: { "Accept": "application/json", "X-Requested-With": "XMLHttpRequest", }, }); api.interceptors.response.use( (response) => response, (error) => { if (error.response?.status === 401) { throw redirect("/login"); } return Promise.reject(error); } ); export default api; ``` Secure Session Management Instead of storing tokens in `localStorage`, we use encrypted cookies. This mitigates Cross-Site Scripting (XSS) risks. In `services/oauth.server.js`, we initialize the cookie storage. ```javascript import { createCookieSessionStorage } from "@remix-run/node"; export const storage = createCookieSessionStorage({ cookie: { name: "_session", secure: process.env.NODE_ENV === "production", secrets: [process.env.SESSION_SECRET], sameSite: "lax", path: "/", maxAge: 60 * 60 * 24 * 30, httpOnly: true, }, }); ``` Syntax Notes Remix uses **loaders** for GET requests and **actions** for mutations. By throwing a `redirect()` object within an interceptor, you can halt the execution flow and force the browser to a new URL, a pattern that simplifies authentication checks across multiple routes. Practical Examples This architecture is ideal for high-security applications like dashboards or booking systems. By fetching data in the loader, Remix populates the page before it reaches the user, improving SEO and perceived performance. Tips & Gotchas Always include the `Accept: application/json` header. Without it, Laravel might return HTML error pages instead of JSON during a failure. Remember that `httpOnly` cookies cannot be accessed by client-side scripts, so all token logic must reside in your server-side files.
Dec 13, 2021Overview Connecting a Nuxt.js frontend to a Laravel REST API creates a powerful, SEO-friendly architecture. By using session-based authentication rather than just tokens, you gain the native security benefits of CSRF protection and reduced XSS risks. This guide explores how to synchronize these environments to share cookies and fetch data seamlessly using a first-party frontend approach. Prerequisites To follow along, you need a working knowledge of JavaScript and PHP. You should have a Laravel API already configured and Nuxt.js (version 2 is used here) installed. Basic familiarity with terminal commands and local development environments like Laravel Valet will help you manage local subdomains. Key Libraries & Tools * Axios: A promise-based HTTP client for the browser and Node.js. * Nuxt Auth Module: A dedicated library to handle authentication strategies. * Laravel Sanctum: Provides a featherweight authentication system for SPAs and simple APIs. * Tailwind CSS: A utility-first CSS framework for rapid UI development. Environment Synchronization For session-based auth to work, both apps must share a top-level domain. Use Laravel Valet to link your API to `api.ergodnc.test` and proxy your Nuxt app to `app.ergodnc.test`. In your Laravel `.env`, set `SESSION_DOMAIN` to `.ergodnc.test`. This dot prefix is non-negotiable; it tells the browser the cookie belongs to all subdomains. Additionally, update `cors.php` by setting `supports_credentials` to `true` to allow the browser to pass cookies back and forth. Code Walkthrough: Data Fetching and Auth In your Nuxt pages, the `fetch` hook is your best friend. It allows you to populate data on the server side or during client-side navigation. ```javascript async fetch() { const response = await this.$axios.get('/offices'); this.offices = response.data; } ``` For authentication, configure the Nuxt Auth Module in `nuxt.config.js` using the `cookie` strategy. You must define four critical endpoints: `login`, `logout`, `user`, and the Sanctum `client-side-csrf` cookie. This ensures Nuxt initializes the CSRF token before attempting a login. Syntax Notes Nuxt’s `fetchState` is an elegant way to handle UI states. Use `$fetchState.pending` to show loaders and `$fetchState.error` to catch failures. When using the Nuxt Auth Module, the `$auth` helper becomes globally available, allowing you to check `$auth.loggedIn` or access user data via `$auth.user` directly in your templates. Tips & Gotchas Always verify that your Laravel Sanctum stateful domains include your Nuxt URL. If you miss this, Laravel won't attach the session middleware, and your authentication will fail silently. If you get 401 errors after a session expires, use an Axios interceptor to catch the error and force a logout on the frontend to keep the UI in sync with the server.
Dec 6, 2021Overview of Next-Generation Spark Laravel Spark serves as a dedicated SaaS toolkit designed to handle the heavy lifting of recurring billing. Unlike earlier versions, the next generation of Spark is front-end agnostic, meaning it provides a totally isolated billing portal that exists separately from your main application logic. This architectural shift grants you total freedom to use any stack—whether Vue.js, React, or simple Blade templates—without the billing logic cluttering your UI. Prerequisites and Toolkit To follow this implementation, you should be comfortable with the Laravel framework and basic terminal operations. Key Libraries & Tools * **Laravel Breeze**: A minimal, simple starter kit for scaffolding authentication. * **Paddle**: A merchant of record that handles VAT taxes and provides PayPal integration. * **Stripe**: The alternative payment provider supported by Spark. * **Tailwind CSS**: The utility-first CSS framework used for branding the portal. Implementation Walkthrough Start by scaffolding authentication using Laravel Breeze. Once your users can log in, install the Paddle edition of Spark via Composer: ```bash composer require laravel/spark-paddle php artisan spark:install ``` Next, integrate the `Billable` trait into your `User` model. This connects your database entities to the Spark billing engine. ```python use Spark\Billable; class User extends Authenticatable { use Billable; } ``` Configuring Subscription Plans Plans reside in `config/spark.php`. Here, you define your monthly and yearly IDs—which you fetch from your Paddle dashboard—along with feature lists. Spark uses these to automatically generate the pricing toggle in the billing portal. Branding and UI Integration Customizing the portal to match your brand (like the green aesthetic of Laravel Forge) happens in the `branding` section of the config. You can swap the logo and primary button colors using Tailwind CSS classes. To link users to the portal, simply point a navigation link to the `/billing` route defined in your configuration. Practical Tips & Gotchas Always use the `onTrial` method to show trial banners in your UI. One common mistake is forgetting to set up webhooks; Laravel Spark relies on webhooks to process subscription status changes. If your local environment isn't receiving these, your application won't know when a user has successfully paid.
Feb 11, 2021The Architecture of Choice in Laravel 8 Laravel 8 marks a significant shift in how we approach the front-end, or more accurately, how we don't. By default, the framework remains entirely agnostic. When you run `laravel new`, you get Blade templates and nothing else. No Tailwind, no Vue, and certainly no forced architectural patterns. This is intentional. The goal is to provide a clean slate while offering powerful, optional scaffolding for those who want to move faster. Much of the recent noise in the community suggests that using tools like Inertia.js or Livewire is a requirement or a "betting of the farm" on immature tech. This fundamentally misunderstands what these tools do. Inertia isn't a massive framework; it's a bridge that lets you use Laravel's routing to hydrate Vue components. It keeps you productive by removing the need for a separate API repository, which is often a productivity killer for solo developers and small teams. Demystifying the Starter Kits: Breeze and Jetstream To understand where you should start, you have to look at the complexity of your requirements. Laravel Breeze represents the baseline. It is a simple, minimal implementation of all Laravel's authentication features—login, registration, password reset—using simple controllers and routes that you can actually see and modify in your app. It’s the spiritual successor to the old `make:auth` command, but modernized with Tailwind. Laravel Jetstream sits at the other end of the spectrum. It is essentially the free, open-source core of what used to be Laravel Spark. We moved all the non-billing features—team management, two-factor authentication, and API token management—out of Spark and into Jetstream. It uses Laravel Fortify as its headless backend. This means Jetstream handles the UI (via either Inertia or Livewire), while Fortify handles the heavy lifting of authentication logic in the background. Passport vs. Sanctum: Choosing Your API Guard The most persistent confusion in our ecosystem revolves around Laravel Passport and Laravel Sanctum. The decision tree is actually quite simple: if you need to build a full OAuth2 server—the kind where users can "Sign in with Your App" on third-party sites—you need Passport. It is a robust, compliant implementation built on the league/oauth2-server. However, most developers don't actually need OAuth2. They just need to secure an API or a Single Page Application (SPA). For these use cases, Passport is a sledgehammer. Sanctum was built to solve the "API for myself" problem. It provides a lightweight way to issue personal access tokens and, more importantly, a way to authenticate SPAs using secure, stateful cookies. The Secret Sauce of SPA Authentication Sanctum's true power lies in its ability to toggle between token-based and cookie-based authentication. When your SPA sits on the same top-level domain as your Laravel API, you shouldn't be messing with JWT storage in `localStorage`. It’s insecure and unnecessary. Instead, Sanctum allows your SPA to call a login endpoint, which uses standard Laravel session guards to issue a secure HTTP-only cookie. The browser then handles that cookie automatically for every subsequent request. If a request comes in without a cookie, the Sanctum guard looks for a `Bearer` token in the header. This dual-layer approach allows the same API routes to serve your first-party SPA via cookies and third-party mobile apps or SDKs via tokens. It’s the most secure and streamlined way to handle modern web authentication without the overhead of a full OAuth2 handshake. Community Dynamics and Open Contributions There is a narrative that the Laravel ecosystem is a closed circle, but the data proves otherwise. With over 2,800 contributors, the "inner circle" is massive. Developers like Paris Malhotra prove that anyone can show up, submit high-quality pull requests to core packages like Laravel Horizon, and get them merged. This isn't about personal friendships; it's about labor and merit. People like Caleb Porzio and Jonathan Reinink earned their status through hundreds of hours of free work to make the ecosystem better. We want people who bring positive energy and a desire to make programming more enjoyable. If you're here to armchair quarterback, you're missing the point of what we're building.
Dec 31, 2020