ninjaportal / shadow-theme
Blade + Alpine.js developer portal theme for NinjaPortal
Requires
- php: ^8.2
- chillerlan/php-qrcode: ^5.0
- illuminate/contracts: ^11.0||^12.0
- illuminate/support: ^11.0||^12.0
- ninjaportal/portal: ^0.1
- spatie/laravel-package-tools: ^1.16
Suggests
- ninjaportal/portal-mfa: Adds MFA setup and login challenge support in the theme
This package is auto-updated.
Last update: 2026-03-02 18:19:20 UTC
README
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
- 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-mfais installed and enabled - Reusable Blade components for building custom pages
Requirements
- Laravel 11 or 12
- PHP
^8.2 ninjaportal/portalinstalled and configured- Tailwind CSS v4 in your application Vite setup
- Node.js + npm/pnpm/yarn for frontend asset builds
Installation
1. Install the package
composer require ninjaportal/shadow-theme
2. Ensure the core portal package is configured
Shadow Theme expects the NinjaPortal core to be available and configured:
ninjaportal/portallordjoo/laraapigee(used by portal for Apigee-backed app/credential operations)
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.nameportal.taglineportal.support_emailshadow.branding.logo_textbranding.primary_colorbranding.secondary_color
This publishes ready-to-use assets to:
public/vendor/shadow-theme/shadow-theme.csspublic/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)
npm install alpinejs daisyui
Tailwind v4 + daisyUI Integration
Shadow Theme can run in two modes:
- Published pre-built assets
- 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
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
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
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)
Shadow Theme implements its own session-based auth flow for developer/consumer users.
This means:
- it does not depend on
portal-apilogin endpoints - it does not use
portal-apiJWT token issuance for the web theme - it talks directly to
ninjaportal/portalservices and models
This is intentional so the Blade theme can be used independently from the REST API package.
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
The package registers an anonymous component namespace:
x-shadow::*
Included components:
x-shadow::ui.flashx-shadow::ui.cardx-shadow::ui.page-headerx-shadow::ui.inputx-shadow::ui.textareax-shadow::ui.selectx-shadow::ui.empty-statex-shadow::product.cardx-shadow::app.status-badge
These can be reused in your own application pages to maintain a consistent UI style.
View Customization
You can customize the theme in two main ways:
- Adjust branding/theme values in
config/shadow-theme.php - Override/publish package views and customize the Blade templates
Notes
- Shadow Theme uses
ninjaportal/portalservices directly (noportal-apiruntime 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.