PHPackages                             ninjaportal/shadow-theme - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. ninjaportal/shadow-theme

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

ninjaportal/shadow-theme
========================

Blade + Alpine.js developer portal theme for NinjaPortal

0.1.3(2mo ago)04MITPHPPHP ^8.2

Since Feb 28Pushed 2mo agoCompare

[ Source](https://github.com/ninjaportal/shadow)[ Packagist](https://packagist.org/packages/ninjaportal/shadow-theme)[ RSS](/packages/ninjaportal-shadow-theme/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (4)Dependencies (5)Versions (6)Used By (0)

NinjaPortal Shadow Theme
========================

[](#ninjaportal-shadow-theme)

`shadow-theme` is a Blade + Alpine.js + Tailwind CSS v4 + daisyUI frontend theme package for NinjaPortal.

It provides a production-ready developer portal UI that integrates directly with `ninjaportal/portal` services (and LaraApigee through the portal package), without relying on `portal-api`.

What It Covers
--------------

[](#what-it-covers)

- Landing page for a developer portal
- API product catalog browsing, searching, and detail pages
- Developer signup, sign in, sign out
- Password reset request + password reset completion
- Session-based auth flow implemented inside the theme package (not JWT / not `portal-api`)
- Developer profile management
- Developer app management (create/update/delete/approve/revoke)
- Developer credential management (create/approve/revoke/delete)
- Credential product management (add/remove/approve/revoke product access)
- Optional MFA (authenticator app + email OTP) when `ninjaportal/portal-mfa` is installed and enabled
- Reusable Blade components for building custom pages

Requirements
------------

[](#requirements)

- Laravel 11 or 12
- PHP `^8.2`
- `ninjaportal/portal` installed and configured
- Tailwind CSS v4 in your application Vite setup
- Node.js + npm/pnpm/yarn for frontend asset builds

Installation
------------

[](#installation)

### 1. Install the package

[](#1-install-the-package)

```
composer require ninjaportal/shadow-theme
```

### 2. Ensure the core portal package is configured

[](#2-ensure-the-core-portal-package-is-configured)

Shadow Theme expects the NinjaPortal core to be available and configured:

- `ninjaportal/portal`
- `lordjoo/laraapigee` (used by portal for Apigee-backed app/credential operations)

### 3. Run the Shadow Theme installer

[](#3-run-the-shadow-theme-installer)

```
php artisan shadow:install --publish-config
```

What it does:

- publishes the pre-built package assets by default
- optionally publishes the package config and views
- checks Portal settings storage (via `SettingServiceInterface`)
- seeds missing branding/runtime settings used by the theme (without overwriting existing values)
    - `portal.name`
    - `portal.tagline`
    - `portal.support_email`
    - `shadow.branding.logo_text`
    - `branding.primary_color`
    - `branding.secondary_color`

This publishes ready-to-use assets to:

- `public/vendor/shadow-theme/shadow-theme.css`
- `public/vendor/shadow-theme/shadow-theme.js`

When these files exist, Shadow Theme will load them automatically.

If you need to skip asset publishing for any reason:

```
php artisan shadow:install --without-assets
```

### 4. Install frontend dependencies (optional if you use published assets)

[](#4-install-frontend-dependencies-optional-if-you-use-published-assets)

```
npm install alpinejs daisyui
```

Tailwind v4 + daisyUI Integration
---------------------------------

[](#tailwind-v4--daisyui-integration)

Shadow Theme can run in two modes:

1. Published pre-built assets
2. Host application Vite/Tailwind integration

If you prefer the host application pipeline, Shadow Theme renders Blade views, so your application Tailwind build must scan the package views.

Update your Tailwind v4 entry CSS (example: `resources/css/app.css`):

```
@import 'tailwindcss';
@plugin "daisyui";

/* Composer-installed package path */
@source '../../vendor/ninjaportal/shadow-theme/resources/views/**/*.blade.php';

/* Optional: local package path (useful in monorepos) */
@source '../../packages/shadow-theme/resources/views/**/*.blade.php';
```

Initialize Alpine in your application JS entry (example: `resources/js/app.js`):

```
import Alpine from 'alpinejs';

window.Alpine = Alpine;
Alpine.start();
```

You can force Shadow Theme to use the host application's build instead of published assets with:

```
SHADOW_THEME_PREFER_PUBLISHED_ASSETS=false
```

Configuration
-------------

[](#configuration)

Publish the config file if you want to customize branding, routing, and features:

```
php artisan vendor:publish --tag=shadow-theme-config
```

Main config file:

- `config/shadow-theme.php`

Shadow Theme will prefer Portal runtime settings (loaded from DB by the Portal package) for branding values when present.

### Common env keys

[](#common-env-keys)

```
SHADOW_THEME_ENABLED=true
SHADOW_THEME_ROUTE_PREFIX=portal
SHADOW_THEME_BRAND_NAME="NinjaPortal"
SHADOW_THEME_BRAND_TAGLINE="A modern developer portal experience for your APIs."
SHADOW_THEME_LOGO_TEXT="Shadow"
SHADOW_THEME_SUPPORT_EMAIL=support@example.com

SHADOW_THEME_DEFAULT_MODE=dark
SHADOW_THEME_LIGHT_DAISY_THEME=corporate
SHADOW_THEME_DARK_DAISY_THEME=night

SHADOW_THEME_REGISTRATION_ENABLED=true
SHADOW_THEME_PASSWORD_RESET_ENABLED=true
SHADOW_THEME_MFA_UI_ENABLED=true
```

Route Mounting
--------------

[](#route-mounting)

By default, the theme is mounted under:

- `/portal`

Examples:

- `/portal`
- `/portal/products`
- `/portal/login`
- `/portal/dashboard`
- `/portal/apps`

Set `SHADOW_THEME_ROUTE_PREFIX=` (empty value) to mount it at the root of your application.

Auth Flow (Important)
---------------------

[](#auth-flow-important)

Shadow Theme implements its own **session-based** auth flow for developer/consumer users.

This means:

- it does **not** depend on `portal-api` login endpoints
- it does **not** use `portal-api` JWT token issuance for the web theme
- it talks directly to `ninjaportal/portal` services and models

This is intentional so the Blade theme can be used independently from the REST API package.

Optional MFA Support
--------------------

[](#optional-mfa-support)

If `ninjaportal/portal-mfa` is installed and enabled, Shadow Theme automatically adds:

- login MFA challenge page (consumer side)
- MFA settings page under the developer profile area
- authenticator app enrollment flow
- email OTP enrollment flow

Shadow Theme integrates with the MFA drivers/services directly and still keeps a session-based login flow for the web UI.

Reusable Blade Components
-------------------------

[](#reusable-blade-components)

The package registers an anonymous component namespace:

- `x-shadow::*`

Included components:

- `x-shadow::ui.flash`
- `x-shadow::ui.card`
- `x-shadow::ui.page-header`
- `x-shadow::ui.input`
- `x-shadow::ui.textarea`
- `x-shadow::ui.select`
- `x-shadow::ui.empty-state`
- `x-shadow::product.card`
- `x-shadow::app.status-badge`

These can be reused in your own application pages to maintain a consistent UI style.

View Customization
------------------

[](#view-customization)

You can customize the theme in two main ways:

1. Adjust branding/theme values in `config/shadow-theme.php`
2. Override/publish package views and customize the Blade templates

Notes
-----

[](#notes)

- Shadow Theme uses `ninjaportal/portal` services directly (no `portal-api` runtime dependency for the theme flow).
- Authentication in Shadow Theme is session-based and separate from the JWT auth flow used in `portal-api`.
- App and credential operations are Apigee-backed through LaraApigee via the portal service layer.

###  Health Score

35

—

LowBetter than 79% of packages

Maintenance85

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 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

4

Last Release

76d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/572472a15d795bd58c160445f6e9298cd82b756bf4355e860491785b5398d6f7?d=identicon)[Youssef20](/maintainers/Youssef20)

---

Top Contributors

[![lordjoo](https://avatars.githubusercontent.com/u/11289152?v=4)](https://github.com/lordjoo "lordjoo (9 commits)")

### Embed Badge

![Health badge](/badges/ninjaportal-shadow-theme/health.svg)

```
[![Health](https://phpackages.com/badges/ninjaportal-shadow-theme/health.svg)](https://phpackages.com/packages/ninjaportal-shadow-theme)
```

###  Alternatives

[spatie/laravel-livewire-wizard

Build wizards using Livewire

4061.0M4](/packages/spatie-laravel-livewire-wizard)[nativephp/mobile

NativePHP for Mobile

82724.0k43](/packages/nativephp-mobile)[tonysm/importmap-laravel

Use ESM with importmap to manage modern JavaScript in Laravel without transpiling or bundling.

148399.8k1](/packages/tonysm-importmap-laravel)[illuminate/pipeline

The Illuminate Pipeline package.

9446.6M213](/packages/illuminate-pipeline)[laracraft-tech/laravel-useful-additions

A collection of useful Laravel additions!

58109.4k](/packages/laracraft-tech-laravel-useful-additions)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

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