Try Live
Add Docs
Rankings
Pricing
Docs
Install
Theme
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
Blueprint Framework
https://github.com/blueprintframework/framework
Admin
Blueprint is an open-source modding framework and extension manager for the Pterodactyl game server
...
Tokens:
10,575
Snippets:
53
Trust Score:
8.6
Update:
3 months ago
Context
Skills
Chat
Benchmark
44.8
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Blueprint Framework Blueprint is an open-source extension framework and manager for the Pterodactyl panel, designed to enable developers to create versatile, easy-to-install extensions that system administrators can install within minutes. The framework eliminates the need for custom-coded compatibility across multiple panel modifications, providing a standardized approach to extending Pterodactyl's functionality. Blueprint aims to lower the barrier to entry for new developers through comprehensive guides, documentation, developer commands, and robust community support. The framework operates on three primary levels: a command-line interface for extension lifecycle management (installation, removal, building, and development), a PHP-based extension library API for runtime integration, and a React-based UI component library for frontend development. Extensions are distributed as `.blueprint` files (ZIP archives) containing a `conf.yml` configuration file that defines metadata, file locations, routes, database migrations, and frontend components. Blueprint handles the complete extension lifecycle—from extracting and validating extension packages to copying files, running migrations, registering routes, injecting frontend components, and rebuilding panel assets. The framework provides Bash CLI tools for system administrators and developers, PHP libraries for extension developers to interact with the Pterodactyl panel's admin interface and database, and React UI components for building consistent, themeable frontend interfaces. ## CLI Commands ### Extension Installation Install a Blueprint extension from a `.blueprint` package file. The installation process extracts the package, validates the configuration, copies files to appropriate directories, runs database migrations, registers routes, and rebuilds panel assets. ```bash # Install an extension blueprint -install myextension.blueprint # Alternative syntax blueprint -add myextension.blueprint blueprint -i myextension.blueprint # Example output # Installing myextension... (1/1) # Validating extension configuration... # Copying files... # Running database migrations... # Registering routes... # Rebuilding assets... # Extension installed successfully! ``` ### Extension Removal Remove an installed Blueprint extension from the Pterodactyl panel. This command removes extension files, database entries, routes, and rebuilds panel assets without the extension. ```bash # Remove an installed extension blueprint -remove extensionid # Alternative syntax blueprint -r extensionid # Example: Remove an extension named 'analytics' blueprint -remove analytics # The identifier is found in the extension's conf.yml file # Output confirms removal and asset rebuild ``` ### Extension Query Query information about an extension, including its metadata, version, author, and installation status. ```bash # Query extension information blueprint -query myextension.blueprint # Alternative syntax blueprint -q myextension.blueprint # Example output: # Name: My Extension # Identifier: myextension # Description: Adds analytics to the panel # Version: 1.0.0 # Author: John Doe # Target: beta-2025-11 # Status: Not installed ``` ### Developer Commands Initialize a new extension project from templates, build extensions from source, and export them for distribution. ```bash # Initialize a new extension in the development directory blueprint -init # Prompts for extension details and creates scaffolding # Build the extension from .blueprint/dev directory blueprint -build # Validates, compiles, and prepares extension for testing # Export extension for distribution blueprint -export # Creates a .blueprint package file in the current directory # Export with public exposure (includes source files) blueprint -export expose # Creates package with readable source code # Wipe the development directory blueprint -wipe # Removes all files from .blueprint/dev # Watch mode for development (auto-rebuild on changes) blueprint -watch ``` ### System Commands Manage Blueprint framework itself, including version information, upgrades, and debugging. ```bash # Show Blueprint version blueprint -version # Show system information blueprint -info # Displays Blueprint version, Pterodactyl version, PHP version, etc. # Show help information blueprint -help # Upgrade Blueprint framework blueprint -upgrade # Downloads and installs latest Blueprint version # Upgrade from remote repository blueprint -upgrade remote # Rerun installation process blueprint -rerun-install # Useful for fixing broken installations # Debug information blueprint -debug # Displays detailed debug logs ``` ## PHP Extension Library API ### Database Operations - Get Single Record Fetch a single record from the database using Blueprint's key-value storage system. Records are stored in the `settings` table with automatic serialization. ```php <?php use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Admin\BlueprintAdminLibrary; class MyExtensionController extends Controller { public function index(BlueprintAdminLibrary $blueprint) { // Get a setting with default value $apiKey = $blueprint->dbGet('myextension', 'api_key', 'default-key'); // Get numeric value $maxUsers = $blueprint->dbGet('myextension', 'max_users', 100); // Get array/object (automatically unserialized) $settings = $blueprint->dbGet('myextension', 'settings', [ 'enabled' => true, 'theme' => 'dark' ]); // Returns the default value if record doesn't exist $missingValue = $blueprint->dbGet('myextension', 'nonexistent', null); // $missingValue will be null return view('myextension.index', [ 'apiKey' => $apiKey, 'maxUsers' => $maxUsers, 'settings' => $settings ]); } } ``` ### Database Operations - Get Multiple Records Fetch multiple records from the database in a single query, returning an associative array with record names as keys. ```php <?php use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Admin\BlueprintAdminLibrary; class ConfigController extends Controller { public function show(BlueprintAdminLibrary $blueprint) { // Get specific records $values = $blueprint->dbGetMany('myextension', [ 'api_key', 'api_secret', 'webhook_url', 'enabled' ], 'not-set'); // Returns: [ // 'api_key' => 'abc123', // 'api_secret' => 'xyz789', // 'webhook_url' => 'https://example.com/hook', // 'enabled' => true // ] // Get all records for a table (omit second parameter) $allSettings = $blueprint->dbGetMany('myextension', [], null); // Returns all records with 'myextension::*' keys // Access individual values if ($values['enabled']) { $api = new ApiClient($values['api_key'], $values['api_secret']); $api->sendWebhook($values['webhook_url'], $data); } return response()->json($values); } } ``` ### Database Operations - Set Single Record Store a single record in the database. Values are automatically serialized, supporting strings, numbers, arrays, and objects. ```php <?php use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Admin\BlueprintAdminLibrary; use Illuminate\Http\Request; class SettingsController extends Controller { public function update(Request $request, BlueprintAdminLibrary $blueprint) { // Store simple values $blueprint->dbSet('myextension', 'api_key', $request->input('api_key')); $blueprint->dbSet('myextension', 'max_users', 150); $blueprint->dbSet('myextension', 'enabled', true); // Store arrays (automatically serialized) $blueprint->dbSet('myextension', 'allowed_ips', [ '192.168.1.1', '10.0.0.1', '172.16.0.1' ]); // Store complex objects $blueprint->dbSet('myextension', 'theme_config', [ 'primary_color' => '#3B82F6', 'secondary_color' => '#10B981', 'fonts' => ['Inter', 'Roboto'], 'dark_mode' => true ]); // updateOrInsert behavior: creates new record or updates existing $blueprint->dbSet('myextension', 'last_updated', now()->toDateTimeString()); return redirect() ->route('admin.extensions.myextension.index') ->with('success', 'Settings updated successfully'); } } ``` ### Database Operations - Set Multiple Records Store multiple records in a single database operation for improved performance. ```php <?php use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Admin\BlueprintAdminLibrary; use Illuminate\Http\Request; class BulkSettingsController extends Controller { public function updateAll(Request $request, BlueprintAdminLibrary $blueprint) { $validated = $request->validate([ 'api_key' => 'required|string', 'api_secret' => 'required|string', 'webhook_url' => 'required|url', 'enabled' => 'boolean', 'max_retries' => 'integer|min:1|max:10' ]); // Batch update multiple records $blueprint->dbSetMany('myextension', [ 'api_key' => $validated['api_key'], 'api_secret' => $validated['api_secret'], 'webhook_url' => $validated['webhook_url'], 'enabled' => $validated['enabled'] ?? true, 'max_retries' => $validated['max_retries'] ?? 3, 'updated_at' => now()->toDateTimeString() ]); // Use for initial setup $blueprint->dbSetMany('myextension', [ 'installed' => true, 'version' => '1.0.0', 'install_date' => now()->toDateTimeString(), 'license_key' => $this->generateLicenseKey() ]); return response()->json([ 'success' => true, 'message' => 'All settings updated successfully' ]); } } ``` ### Database Operations - Delete Single Record Remove a single record from the database, returning whether the deletion was successful. ```php <?php use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Admin\BlueprintAdminLibrary; class CacheController extends Controller { public function clearApiKey(BlueprintAdminLibrary $blueprint) { // Delete a specific record $deleted = $blueprint->dbForget('myextension', 'api_key'); if ($deleted) { // Record existed and was deleted return response()->json([ 'success' => true, 'message' => 'API key cleared' ]); } else { // Record didn't exist return response()->json([ 'success' => false, 'message' => 'No API key to clear' ], 404); } } public function clearCache(BlueprintAdminLibrary $blueprint) { // Clear temporary data $blueprint->dbForget('myextension', 'cache_data'); $blueprint->dbForget('myextension', 'cache_timestamp'); $blueprint->dbForget('myextension', 'temp_token'); return redirect()->back()->with('success', 'Cache cleared'); } } ``` ### Database Operations - Delete Multiple Records Remove multiple records in a single database operation. ```php <?php use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Admin\BlueprintAdminLibrary; class ResetController extends Controller { public function resetApiSettings(BlueprintAdminLibrary $blueprint) { // Delete multiple related records $deleted = $blueprint->dbForgetMany('myextension', [ 'api_key', 'api_secret', 'api_endpoint', 'api_timeout', 'api_retries' ]); if ($deleted) { return response()->json([ 'success' => true, 'message' => 'API settings reset' ]); } return response()->json([ 'success' => false, 'message' => 'No settings to reset' ], 404); } public function clearSessionData(BlueprintAdminLibrary $blueprint) { // Clear all session-related data $blueprint->dbForgetMany('myextension', [ 'session_token', 'csrf_token', 'temp_data', 'flash_messages' ]); return redirect()->route('admin.extensions.myextension.index'); } } ``` ### Database Operations - Delete All Records Remove all records associated with an extension table, useful for uninstallation or complete resets. ```php <?php use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Admin\BlueprintAdminLibrary; class UninstallController extends Controller { public function uninstall(BlueprintAdminLibrary $blueprint) { // Remove all extension data $deleted = $blueprint->dbForgetAll('myextension'); if ($deleted) { // Log the uninstallation \Log::info('Extension myextension uninstalled, all data removed'); return response()->json([ 'success' => true, 'message' => 'All extension data removed' ]); } return response()->json([ 'success' => false, 'message' => 'No data to remove' ], 404); } public function factoryReset(BlueprintAdminLibrary $blueprint) { // Complete reset to defaults $blueprint->dbForgetAll('myextension'); // Reinstall default settings $blueprint->dbSetMany('myextension', [ 'version' => '1.0.0', 'enabled' => false, 'max_users' => 100, 'theme' => 'default' ]); return redirect() ->route('admin.extensions.myextension.index') ->with('success', 'Extension reset to factory defaults'); } } ``` ### Extension Detection and Management Check if extensions are installed and retrieve their configurations for conditional features or inter-extension compatibility. ```php <?php use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Admin\BlueprintAdminLibrary; class IntegrationController extends Controller { public function checkIntegrations(BlueprintAdminLibrary $blueprint) { // Check if specific extensions are installed $hasAnalytics = $blueprint->extension('analytics'); $hasThemeEngine = $blueprint->extension('themeengine'); $hasBilling = $blueprint->extension('billing'); // Enable features based on installed extensions if ($hasAnalytics) { $this->enableAnalyticsIntegration(); } // Get list of all installed extensions $installedExtensions = $blueprint->extensions(); // Returns: ['analytics', 'themeengine', 'myextension', ...] // Get configuration for specific extension if ($hasThemeEngine) { $themeConfig = $blueprint->extensionConfig('themeengine'); // Returns parsed conf.yml as array: // [ // 'info' => [ // 'name' => 'Theme Engine', // 'identifier' => 'themeengine', // 'version' => '2.0.0', // ... // ], // 'admin' => [...], // 'dashboard' => [...] // ] $themeName = $themeConfig['info']['name']; $themeVersion = $themeConfig['info']['version']; } // Get all extension configurations $allConfigs = $blueprint->extensionsConfigs(); // Returns Laravel Collection of all conf.yml files return view('myextension.integrations', [ 'hasAnalytics' => $hasAnalytics, 'installedExtensions' => $installedExtensions, 'extensionCount' => count($installedExtensions) ]); } } ``` ### Admin Library - Display Alerts Display flash alerts at the top of admin pages using Laravel's alert system with automatic styling for different message types. ```php <?php use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Admin\BlueprintAdminLibrary; use Illuminate\Http\Request; class AdminController extends Controller { public function update(Request $request, BlueprintAdminLibrary $blueprint) { try { $this->updateSettings($request->all()); // Success alert (green) $blueprint->alert('success', 'Settings updated successfully!'); } catch (\Exception $e) { // Danger alert (red) $blueprint->alert('danger', 'Failed to update settings: ' . $e->getMessage()); } return redirect()->route('admin.extensions.myextension.index'); } public function configure(BlueprintAdminLibrary $blueprint) { $apiKey = $blueprint->dbGet('myextension', 'api_key', null); if (!$apiKey) { // Warning alert (yellow/orange) $blueprint->alert('warning', 'API key not configured. Some features may not work.'); } // Info alert (blue) $blueprint->alert('info', 'Remember to save your changes before leaving this page.'); return view('myextension.configure'); } public function maintenance(BlueprintAdminLibrary $blueprint) { // Multiple alerts can be chained $blueprint->alert('info', 'Starting maintenance tasks...'); $results = $this->runMaintenanceTasks(); if ($results['success']) { $blueprint->alert('success', "Maintenance completed. {$results['count']} items processed."); } else { $blueprint->alert('danger', 'Maintenance failed. Check logs for details.'); } return redirect()->back(); } } ``` ### Admin Library - Import Assets Import stylesheets and scripts into admin pages with automatic cache-busting to ensure users receive updated assets. ```php <?php use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Admin\BlueprintAdminLibrary; class AdminViewController extends Controller { public function index(BlueprintAdminLibrary $blueprint) { // Import custom stylesheet $cssLink = $blueprint->importStylesheet('/extensions/myextension/admin.css'); // Returns: <link rel="stylesheet" href="/extensions/myextension/admin.css?v=1234567890"> // Import JavaScript file $jsScript = $blueprint->importScript('/extensions/myextension/admin.js'); // Returns: <script src="/extensions/myextension/admin.js?v=1234567890"></script> // Import multiple assets $chartJs = $blueprint->importScript('/extensions/myextension/charts.js'); $dashboardCss = $blueprint->importStylesheet('/extensions/myextension/dashboard.css'); $analyticsJs = $blueprint->importScript('/extensions/myextension/analytics.js'); return view('admin.extensions.myextension.index', [ 'cssLink' => $cssLink, 'jsScript' => $jsScript, 'chartJs' => $chartJs, 'dashboardCss' => $dashboardCss, 'analyticsJs' => $analyticsJs ]); } } // In the Blade view (resources/views/admin/extensions/myextension/index.blade.php): // @section('content-header') // {!! $cssLink !!} // {!! $dashboardCss !!} // @endsection // // @section('scripts') // {!! $jsScript !!} // {!! $chartJs !!} // {!! $analyticsJs !!} // @endsection ``` ### Client Library - Import Assets Import stylesheets and scripts into client-facing pages with cache-busting for updated assets. ```php <?php use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Client\BlueprintClientLibrary; class ClientController extends Controller { public function dashboard(BlueprintClientLibrary $blueprint) { // Import client-specific styles $clientCss = $blueprint->importStylesheet('/extensions/myextension/client.css'); // Returns: <link rel="stylesheet" href="/extensions/myextension/client.css?v=1234567890"> // Import client-specific JavaScript $clientJs = $blueprint->importScript('/extensions/myextension/client.js'); // Returns: <script src="/extensions/myextension/client.js?v=1234567890"></script> // Import third-party libraries $vue = $blueprint->importScript('/extensions/myextension/vendor/vue.min.js'); $tailwind = $blueprint->importStylesheet('/extensions/myextension/vendor/tailwind.css'); return view('myextension.client.dashboard', [ 'clientCss' => $clientCss, 'clientJs' => $clientJs, 'vue' => $vue, 'tailwind' => $tailwind ]); } } // In the Blade view: // @section('meta') // {!! $tailwind !!} // {!! $clientCss !!} // @endsection // // @section('content') // <div id="app"> // <!-- Vue application content --> // </div> // @endsection // // @section('scripts') // {!! $vue !!} // {!! $clientJs !!} // @endsection ``` ## React UI Components Library Blueprint provides a suite of pre-built React UI components that match Pterodactyl's design system. These components are accessible via `@blueprint/ui` imports and offer consistent styling, theming support, and enhanced features compared to building custom components. ### UiAlert Component Display styled alert messages with support for different severity levels. Alerts feature a left border accent and appropriate background colors. ```tsx import React from 'react'; import { UiAlert } from '@blueprint/ui'; const MyExtensionPage: React.FC = () => { return ( <div> {/* Info alert (blue) */} <UiAlert type="info"> Your server is running the latest version. </UiAlert> {/* Warning alert (yellow) */} <UiAlert type="warning"> Database backup is recommended before proceeding. </UiAlert> {/* Danger alert (red) */} <UiAlert type="danger"> Critical error: Unable to connect to the database. </UiAlert> {/* Custom styling with className */} <UiAlert type="info" className="mt-4 mb-2"> You can add custom Tailwind classes for spacing and layout. </UiAlert> {/* Complex content */} <UiAlert type="warning"> <div className="flex items-center justify-between"> <span>Your license expires in 7 days.</span> <button className="ml-4 px-3 py-1 bg-yellow-600 rounded"> Renew Now </button> </div> </UiAlert> </div> ); }; export default MyExtensionPage; ``` ### UiBadge Component Render small inline badges for labels, status indicators, counts, or tags. Badges are lightweight and customizable. ```tsx import React from 'react'; import { UiBadge } from '@blueprint/ui'; const ServerList: React.FC = () => { return ( <div className="space-y-4"> {/* Simple badge */} <div> Server Status: <UiBadge>Online</UiBadge> </div> {/* Badge with custom styling */} <div className="flex items-center gap-2"> <span>Version:</span> <UiBadge className="bg-blue-600 text-white">v2.1.0</UiBadge> </div> {/* Count badge */} <div> Active Users: <UiBadge>42</UiBadge> </div> {/* Multiple badges */} <div className="flex gap-2"> <UiBadge>Production</UiBadge> <UiBadge>US-East</UiBadge> <UiBadge>Premium</UiBadge> </div> {/* Badge with click handler */} <UiBadge className="cursor-pointer hover:bg-gray-600" onClick={() => console.log('Badge clicked')} > Click Me </UiBadge> {/* Status indicators */} <div className="flex items-center gap-2"> <UiBadge className="bg-green-600">Active</UiBadge> <UiBadge className="bg-yellow-600">Pending</UiBadge> <UiBadge className="bg-red-600">Error</UiBadge> </div> </div> ); }; export default ServerList; ``` ### UiDivider Component Create visual separators between content sections. Dividers can be plain horizontal lines or include centered text labels. ```tsx import React from 'react'; import { UiDivider } from '@blueprint/ui'; const SettingsPage: React.FC = () => { return ( <div className="space-y-6"> {/* Section 1 */} <div> <h2>General Settings</h2> <p>Configure basic extension settings here.</p> </div> {/* Simple divider */} <UiDivider /> {/* Section 2 */} <div> <h2>API Configuration</h2> <p>Set up your API credentials and endpoints.</p> </div> {/* Divider with label */} <UiDivider>Advanced Options</UiDivider> {/* Section 3 */} <div> <h2>Advanced Settings</h2> <p>Configure advanced features and integrations.</p> </div> {/* Divider with custom spacing */} <UiDivider className="my-8" /> {/* Section 4 */} <div> <h2>Danger Zone</h2> <p>Destructive actions that cannot be undone.</p> </div> {/* Labeled dividers for form sections */} <UiDivider>Database Settings</UiDivider> <div> {/* Database form fields */} </div> <UiDivider>Email Configuration</UiDivider> <div> {/* Email form fields */} </div> <UiDivider>Security</UiDivider> <div> {/* Security form fields */} </div> </div> ); }; export default SettingsPage; ``` ## Extension Configuration File ### conf.yml Structure Define extension metadata, file locations, routes, and integrations in the extension's `conf.yml` configuration file. ```yaml # Extension metadata info: name: "Analytics Dashboard" identifier: "analytics" description: "Advanced analytics and reporting for Pterodactyl servers" version: "2.1.0" target: "beta-2025-11" author: "Your Name <email@example.com>" icon: "icon.png" website: "https://example.com/analytics" # Admin panel integration admin: view: "admin" # Directory containing admin views controller: "admin/AnalyticsController.php" # Admin controller file css: "admin/admin.css" # Admin stylesheet wrapper: "admin/wrapper.blade.php" # Admin layout wrapper # Client dashboard integration dashboard: css: "dashboard/client.css" # Client stylesheet wrapper: "dashboard/wrapper.blade.php" # Client layout wrapper components: "dashboard/components" # React components directory # Data and file locations data: directory: "data" # Private data directory public: "public" # Public assets directory console: "console" # Console commands directory # HTTP routes and controllers requests: views: "views" # Blade views directory app: "app" # Controllers and models routers_web: "routes/web.php" # Web routes routers_client: "routes/client.php" # Client API routes routers_application: "routes/app.php" # Application API routes # Database migrations database: migrations: "database/migrations" # Migration files directory ``` ## Extension Routes ### Admin Extension Routes Define custom admin panel routes for extension configuration and management interfaces. ```php <?php // File: routes/web.php (in extension package) use Illuminate\Support\Facades\Route; use Pterodactyl\Http\Controllers\Admin\Extensions\analytics\AnalyticsExtensionController; // Main extension page: /admin/extensions/analytics Route::get('/', [AnalyticsExtensionController::class, 'index']) ->name('admin.extensions.analytics.index'); // Update settings: PATCH /admin/extensions/analytics Route::patch('/', [AnalyticsExtensionController::class, 'update']) ->name('admin.extensions.analytics.patch'); // Custom routes Route::get('/reports', [AnalyticsExtensionController::class, 'reports']) ->name('admin.extensions.analytics.reports'); Route::get('/export', [AnalyticsExtensionController::class, 'export']) ->name('admin.extensions.analytics.export'); Route::delete('/{target}/{id}', [AnalyticsExtensionController::class, 'delete']) ->name('admin.extensions.analytics.delete'); ``` ### Client API Routes Define client-facing API endpoints for frontend interactions. ```php <?php // File: routes/client.php (in extension package) use Illuminate\Support\Facades\Route; use Pterodactyl\Http\Controllers\Api\Client\Extensions\AnalyticsController; // Get analytics data: GET /api/client/extensions/analytics/data Route::get('/data', [AnalyticsController::class, 'getData']); // Get server metrics: GET /api/client/extensions/analytics/servers/{server}/metrics Route::get('/servers/{server}/metrics', [AnalyticsController::class, 'getServerMetrics']); // Update user preferences: POST /api/client/extensions/analytics/preferences Route::post('/preferences', [AnalyticsController::class, 'updatePreferences']); // Example controller usage: // class AnalyticsController extends ClientApiController // { // public function getData(Request $request) // { // $user = $request->user(); // $analytics = $this->analyticsService->getUserAnalytics($user); // // return response()->json([ // 'data' => $analytics, // 'generated_at' => now()->toIso8601String() // ]); // } // } ``` ## React Component Integration ### Frontend Component Injection Inject React components into Pterodactyl's frontend at predefined extension points. ```typescript // File: dashboard/components/ServerDashboard.tsx import React from 'react'; import { UiAlert, UiBadge, UiDivider } from '@blueprint/ui'; interface ServerMetrics { cpu: number; memory: number; disk: number; } const AnalyticsDashboard: React.FC = () => { const [metrics, setMetrics] = React.useState<ServerMetrics | null>(null); const [error, setError] = React.useState<string | null>(null); React.useEffect(() => { fetch('/api/client/extensions/analytics/data') .then(res => res.json()) .then(data => setMetrics(data.metrics)) .catch(err => setError('Failed to load metrics')); }, []); if (error) { return <UiAlert type="danger">{error}</UiAlert>; } if (!metrics) { return <div>Loading analytics...</div>; } return ( <div className="analytics-dashboard"> <h2>Server Analytics</h2> <UiDivider>Resource Usage</UiDivider> <div className="metrics-grid grid grid-cols-3 gap-4 mt-4"> <div className="metric p-4 bg-gray-800 rounded"> <div className="flex items-center justify-between"> <span>CPU Usage</span> <UiBadge className={metrics.cpu > 80 ? 'bg-red-600' : 'bg-green-600'}> {metrics.cpu}% </UiBadge> </div> </div> <div className="metric p-4 bg-gray-800 rounded"> <div className="flex items-center justify-between"> <span>Memory Usage</span> <UiBadge>{metrics.memory}%</UiBadge> </div> </div> <div className="metric p-4 bg-gray-800 rounded"> <div className="flex items-center justify-between"> <span>Disk Usage</span> <UiBadge>{metrics.disk}%</UiBadge> </div> </div> </div> {metrics.cpu > 80 && ( <UiAlert type="warning" className="mt-4"> High CPU usage detected. Consider upgrading your server resources. </UiAlert> )} </div> ); }; export default AnalyticsDashboard; // Blueprint injects this component at marked injection points in Pterodactyl's React code: // {/* blueprint/import */} - Extensions add imports // {/* blueprint/react */} - Extensions add JSX components ``` Blueprint Framework provides a complete modding ecosystem for Pterodactyl, enabling rapid extension development and deployment. The framework's primary use cases include adding analytics dashboards, implementing billing systems, creating custom themes, integrating third-party services, and extending server management capabilities. Extensions are isolated from each other and from core Pterodactyl code, ensuring compatibility across updates and preventing conflicts between multiple installed extensions. The framework's database abstraction layer simplifies data persistence, the React UI component library provides consistent, themeable interface elements, and the CLI tools streamline the entire development lifecycle from initialization to distribution. Integration patterns follow Laravel and React conventions, with extensions providing controllers, views, routes, migrations, and React components that Blueprint automatically registers during installation. The framework handles asset compilation, cache invalidation, and file permissions, allowing developers to focus on functionality rather than infrastructure. Extensions can detect and interact with other installed extensions, enabling complex integrations like theme engines that other extensions can leverage, or analytics systems that aggregate data from multiple sources. The standardized `conf.yml` format and clear directory structure make extensions easy to audit, maintain, and distribute through Blueprint's ecosystem. With support for both admin panel and client dashboard customizations, as well as reusable UI components through the Blueprint UI library, extensions can provide comprehensive feature additions that feel native to Pterodactyl while maintaining the flexibility and isolation that makes Blueprint a robust modding framework.