PHPackages                             phpspa/client - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. phpspa/client

ActiveProject[Framework](/categories/framework)

phpspa/client
=============

PhpSPA + Vite + Tailwind starter project that mixes PhpSPA pages with hydrated client navigation.

v0.0.1(4mo ago)701MITPHP

Since Dec 21Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/dconco/phpspa-client)[ Packagist](https://packagist.org/packages/phpspa/client)[ Docs](https://phpspa-client.up.railway.app)[ RSS](/packages/phpspa-client/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (1)Versions (4)Used By (0)

🚀 PhpSPA + Vite Starter
=======================

[](#-phpspa--vite-starter)

**A PhpSPA boilerplate that serves PhpSPA pages first, then hydrates navigation with Vite + TypeScript + Tailwind.**

[![PHP Version](https://camo.githubusercontent.com/270717987f5341772d79b57567226e54ed27b2d4199bbdc98a96e2edf24902fa/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342532422d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://www.php.net/)[![Node Version](https://camo.githubusercontent.com/57de081c43bbf2951ffd6a4c1d5e90ec4bc5329d3c4b23e650939723413e0062/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e6f64652d31382532422d3333393933333f6c6f676f3d6e6f64652e6a73266c6f676f436f6c6f723d7768697465)](https://nodejs.org/)[![Vite](https://camo.githubusercontent.com/229076cd0ffa2294281403985185776b3e20fd24ad0bcba5d98e28060fdafa10/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566974652d352e302d3634364346463f6c6f676f3d76697465266c6f676f436f6c6f723d7768697465)](https://vitejs.dev/)[![Tailwind CSS](https://camo.githubusercontent.com/2243d59d7cc80aedff13eba9716462232a83f6590ad29399b7cbcea5241d5aaa/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5461696c77696e642d76342d3338423241433f6c6f676f3d7461696c77696e642d637373266c6f676f436f6c6f723d7768697465)](https://tailwindcss.com/)

[**🌐 Live Preview**](https://phpspa-client.onrender.com) • [Documentation](https://phpspa.tech)

---

✨ What You Get
--------------

[](#-what-you-get)

**🎯 Zero Config**

- PHP renders first request
- PhpSPA handles client nav
- Auto asset switching

**⚡ Lightning Fast**

- Vite HMR &lt; 50ms
- Instant page transitions
- Production optimized

**🎨 Modern Stack**

- Tailwind v4 utilities
- TypeScript ready
- SEO-friendly meta tags

**📦 Everything Included**

- Component system
- State management
- Syntax highlighting

---

📦 Installation
--------------

[](#-installation)

```
composer create-project phpspa/client my-project
cd my-project
```

---

🎯 Quick Start
-------------

[](#-quick-start)

### Step 1: Start Development Servers

[](#step-1-start-development-servers)

```
# Terminal 1 – Vite dev server with HMR
pnpm dev

# Terminal 2 – PHP built-in server
php -S localhost:8000 index.php
```

Open **** in your browser.

---

### ⚠️ IMPORTANT: Development Script Tags

[](#️-important-development-script-tags)

> **🔴 CRITICAL STEP** – This starter supports a Vite-dev workflow by loading Vite’s HTML when the dev server is running.

**To enable Vite HMR during development, add these two lines to `index.html` before ``:**

```

```

#### What each script does:

[](#what-each-script-does)

ScriptPurpose`@vite/client`🔥 Connects browser to Vite HMR server (port 5173) for instant hot module updates`src/main.ts`🎬 Your app entry point: imports styles, registers hooks, boots `@dconco/phpspa` runtime> 💡 **Pro tip:** Leave these in during dev, remove them before deploying to production.

#### How the layout decides what to serve

[](#how-the-layout-decides-what-to-serve)

- In [app/layout/layout.php](app/layout/layout.php) we first try to fetch the Vite dev server (default `http://localhost:5173`).
- If the dev server is **reachable**, we use its HTML (HMR works).
- If it’s **not reachable**, we fall back to `index.html` and load the production assets from `public/assets/.vite/manifest.json`.

#### Changing the Vite dev server URL

[](#changing-the-vite-dev-server-url)

If your Vite server is not `http://localhost:5173` (different host/port), you must update **both**:

- `index.html` (the two `` URLs)
- [app/layout/layout.php](app/layout/layout.php) (`$viteDevOrigin`)

---

🏗️ Production Build
-------------------

[](#️-production-build)

### Step 1: Build Assets

[](#step-1-build-assets)

```
pnpm build
```

This generates optimized, hashed assets in `public/assets/` and creates the Vite manifest.

### Step 2: Deploy

[](#step-2-deploy)

```
php -S localhost:8000 index.php
# Or deploy to Apache/Nginx
```

When dev scripts are missing, `app/layout/layout.php` automatically loads manifest assets.

### Production recommendation

[](#production-recommendation)

Set `APP_ENV=production` in your environment.

- This disables the dev-server probe entirely (no extra network call in production).
- The layout always loads the manifest assets.

---

📜 Available Scripts
-------------------

[](#-available-scripts)

CommandDescription`pnpm dev`🔧 Start Vite dev server with HMR on port 5173`pnpm build`📦 Production build to `public/assets/``pnpm preview`👀 Preview production build served by Vite`pnpm watch`👁️ Continuous build mode for backend-only servers---

🎨 How to Extend
---------------

[](#-how-to-extend)

**Add New Pages**

```
// app/pages/contact.php
return new Component(fn () => 'Contact')
    ->route('/contact')
    ->title('Contact Us')
```

Then attach in `index.php`:

```
$app->attach(require 'app/pages/contact.php');
```

**Add Client Hooks**

```
// src/main.ts
import { useEffect, setState } from '@dconco/phpspa';

useEffect(() => {
    console.log('Page loaded!');
}, []);
```

---

🔎 SEO (Simple + Strong)
-----------------------

[](#-seo-simple--strong)

PhpSPA is **PHP-first**: every route returns real HTML on the first request (not an empty JS shell). That makes SEO straightforward:

- **Search bots see content immediately** (server-rendered HTML response).
- **Dynamic SEO per route**: set `title`, `description`, OpenGraph, etc. right on the route component.
- **Global defaults**: set shared meta tags once in `index.php`.

### Dynamic SEO per route (recommended)

[](#dynamic-seo-per-route-recommended)

Every route can define its own metadata:

```
// app/pages/HomePage.php
new Component($HomePage)
   ->route('/')
   ->title('PhpSPA Design System — Vite + Tailwind + PhpSPA')
   ->meta(name: 'description', content: 'Design-forward PhpSPA starter pairing PHP controllers with Vite, Tailwind, and typed state helpers for seamless SPA navigation.')
   ->meta(property: 'og:title', content: 'PhpSPA Design System — Vite + Tailwind + PhpSPA')
   ->meta(property: 'og:description', content: 'Explore PhpSPA component-driven PHP workflow, instant navigation, and production-ready Vite tooling.');
```

> You can do the same for every page (see `app/pages/AboutPage.php` and `app/pages/DocsPage.php`).

### Global SEO defaults

[](#global-seo-defaults)

Set shared defaults once in `index.php`:

```
new App()
    ->meta(charset: 'UTF-8')
    ->meta(name: 'viewport', content: 'width=device-width, initial-scale=1.0');
```

### Canonical URLs (production)

[](#canonical-urls-production)

In production you should output a canonical link per request. This template includes a production-only canonical example in `index.php`.

---

🤝 Contributing
--------------

[](#-contributing)

Issues and PRs welcome! Visit [phpspa.tech](https://phpspa.tech) for full documentation.

---

**Built with ❤️ using PhpSPA + Vite**

[Documentation](https://phpspa.tech) • [GitHub](https://github.com/dconco/phpspa) • [NPM Package](https://www.npmjs.com/package/@dconco/phpspa)

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance77

Regular maintenance activity

Popularity6

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity27

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

148d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/aff7e7d7d6268a283ff2f4968de6430a826972a58b9d719cdea57b98aaf5fdb2?d=identicon)[dconco](/maintainers/dconco)

---

Top Contributors

[![dconco](https://avatars.githubusercontent.com/u/118613296?v=4)](https://github.com/dconco "dconco (25 commits)")

---

Tags

phpvitestarterSPAphpspa

### Embed Badge

![Health badge](/badges/phpspa-client/health.svg)

```
[![Health](https://phpackages.com/badges/phpspa-client/health.svg)](https://phpackages.com/packages/phpspa-client)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
