Welcome to the SaaShovel Documentation! This guide provides
everything you need to know to set up, customize, and get the most out of SaaShovel. Whether
you're just getting started or looking to explore advanced features, this documentation will
help you make the most of your SaaS experience with SaaShovel.
Check out our GitHub repository for the latest code and updates.
Development Environment:
We recommend using one of these options for the best development experience:
- Laravel Herd (Windows/macOS) - fastest native environment
- Laravel Sail (all platforms) - Docker-based solution
- Laragon (Windows) - full-featured local server
- Laravel Valet (macOS) - lightweight option
- Laravel Homestead (all platforms) - VM-based environment
Note: Make sure all PHP extensions are installed and enabled before proceeding with the installation. You can check your PHP configuration by running php -m in your terminal.
Clone the SaaShovel repository (or download it from GitHub). You will need to generate a PAT (Personal Access Token). More information on how to generate it can be found here.
Navigate to the SaaShovel folder
Copy the ".env.example" file and rename it to ".env" to configure your app. More information is provided below in point 5.
Install PHP dependencies
Install Node.js dependencies
Then
This command will:
Change the host url in the "vite.config.js" file to your local dev url.
ThenFinally
Update your .env file with the following settings:
The names must strictly match (case-sensitive) the subscription tier names you've set in your billing provider's dashboard.
Pro Tip: For a Step By Step guide on how to create subscription plans, please click here
Remember to never commit your .env file to version control. Keep your API keys and secrets secure!
Pro Tip: Most configuration options can be modified through:
Main folders to customize:
Make sure to review the documentation before making significant changes. Each component is documented with its available props and usage examples.
SaaShovel provides several custom artisan commands to streamline your development workflow:
Initialize your SaaShovel project
This command will:
Reset your application to a clean state
This command will:
Pro Tip: Use saashovel:flush during development to quickly reset your application state. Be careful not to use it in production as it will erase all data!
Generate a new Livewire page component with proper structure
This command will create:
Delete all subscription plans from the database (useful for a plan data refresh)
This command will:
Set up application for development mode
This command will:
Pro Tip: After running saashovel:dev, don't forget to start the Vite development server with npm run dev. Review the development checklist to ensure everything is properly configured.
Deploy application to production mode
This command will:
Pro Tip: Use saashovel:prod when deploying to production. Make sure to review the post-deployment checklist displayed after completion. Always test in a staging environment first!
SaaShovel supports multiple payment processors, configurable via the
BILLING_PROVIDER environment variable.
Configure multiple payment methods by:
BILLING_PROVIDER=paddle)
For exclusive cryptocurrency payments, set
BILLING_PROVIDER=nowpayments
SaaShovel automatically handles the entire subscription process. Users can manage their subscriptions through:
All providers include a "Cancel Plan" button for easy subscription cancellation.
Features:
Note: For pricing plan design customization, please refer to the Components section of this documentation.
.env file, ensuring all necessary
variables are set..env file match exactly with your provider's
dashboard.FIRST_TIER_SUBSCRIPTION_NAME,
SECOND_TIER_SUBSCRIPTION_NAME, or
THIRD_TIER_SUBSCRIPTION_NAMESTRIPE_KEY
in your .envSTRIPE_SECRETcustomer.subscription.* events)STRIPE_WEBHOOK_SECRET in your .envFIRST_TIER_SUBSCRIPTION_NAME,
SECOND_TIER_SUBSCRIPTION_NAME, or
THIRD_TIER_SUBSCRIPTION_NAMELEMON_SQUEEZY_API_KEY in your
.env#XXXXXX) without the "#"
LEMON_SQUEEZY_STORE in your .env
LEMON_SQUEEZY_SIGNING_SECRET in your .env
FIRST_TIER_SUBSCRIPTION_NAME,
SECOND_TIER_SUBSCRIPTION_NAME, or
THIRD_TIER_SUBSCRIPTION_NAMEPADDLE_VENDOR_IDPADDLE_VENDOR_AUTH_CODEPADDLE_PUBLIC_KEYPADDLE_CLIENT_SIDE_TOKENPADDLE_WEBHOOK_SECRETPADDLE_SANDBOX=true in your .envFIRST_TIER_SUBSCRIPTION_NAME,
SECOND_TIER_SUBSCRIPTION_NAME, or
THIRD_TIER_SUBSCRIPTION_NAME.env:
NOWPAYMENTS_EMAILNOWPAYMENTS_PASSWORDNOWPAYMENTS_API_KEYNOWPAYMENTS_IPN_SECRETNOWPAYMENTS_CURRENCY
(e.g., USD)NOWPAYMENTS_BASE_URL=https://api-sandbox.nowpayments.io/v1/
Webhook listeners are located in the app/Listeners/ directory.
Handled through Laravel's Cashier package.
Implemented using the LemonSqueezy Laravel package.
Managed by SaaShovel's proprietary package
(tcja/nowpayments-laravel).
Testing Webhooks Locally:
SaaShovel provides flexibility in changing billing providers without service interruption.
In case of billing provider issues (e.g., account suspension), you can:
BILLING_PROVIDER to an alternative provider.While the app supports multiple billing providers simultaneously:
Note: While multiple provider support offers flexibility, maintaining subscriptions across different providers may lead to complex database records. Consider consolidating to a single provider (or the hybrid method with NOWPayments) for cleaner data management.
The application uses two main layouts located in resources/views/layouts:
app.blade.php - This layout is used when users are logged into their
dashboard.
guest.blade.php - This layout is used for:
The navigation menu is implemented in two locations:
resources/views/components/navigation-menu.blade.php (for dashboard
layout)resources/views/components/header.blade.php (for public layout)
<!-- Blog menu code -->
@@php $menu = \LaraZeus\Sky\SkyPlugin::get()->getModel('Navigation')::fromHandle('main'); @endphp
@@if ($menu && $menu->items)
@@foreach ($menu->items as $item)
@{!! \App\CustomRenderNavItem::render($item, $menuLinkClass) !!}
@@endforeach
@@endif
<!-- /Blog menu code -->
This code automatically displays pages created through the CMS. The default menu handle is "main".
Add links manually below the CMS menu code:
<!-- Site links -->
<div class="bg-gray-100 p-4 rounded-md font-mono text-sm mt-2">
<a href="#features" class="class">Features</a>
<a href="#pricing" class="class">Pricing</a>
</div>
<!-- /Site links -->
Note: When creating menus through the CMS, ensure you use the "main" handle for the menu to display properly, or update the handle in the code if you prefer a different name.
Saashovel supports automatic locale detection based on browser settings. Configure this in your .env file:
Tip: Set APP_USE_BROWSER_LOCALE to true to automatically serve content in the user's preferred language.
The application uses Laravel's standard JSON-based localization system. Locale files are organized in different locations based on their purpose:
resources/lang/
resources/lang/vendor/zeus-sky/
resources/lang/vendor/zeus-wind/
Note: Saashovel comes with multiple language translations out of the box. Make sure to:
Users with admin rights are automatically redirected to the admin panel upon login. The
panel consists of several tabs, each serving specific administrative functions.
It is powered by the powerful Filament
package.
Features integrated Google Analytics widgets. To enable:
GOOGLE_ANALYTICS_WIDGETS=true in your .env file to display
widgets
Comprehensive user management interface for adding, removing, and updating user
data.
Impersonate users to assist them with any issues they encounter by clicking on the
icon.
Direct environment variable management interface.
Warning: Modifying critical variables (APP_NAME, APP_KEY) may require re-authentication and could affect application functionality.
Configure contact form departments. The contact form remains functional even without departments.
View and manage submitted contact form messages.
Contact page views can be customized at:
resources/views/vendor/zeus/themes/zeus/wind
Note: The contact feature is based on https://github.com/lara-zeus/wind. Visit their documentation for more customization information.
Create and manage pages with granular permission control. Configure URL prefixes using:
BLOG_URL_PREFIX (must not be empty to avoid auth routing
issues)BLOG_PAGE_URL_PREFIX
Page layout template:
resources/views/vendor/zeus/themes/zeus/sky/page.blade.php
Create and manage FAQ pages. Configure URL prefix using
BLOG_FAQ_URL_PREFIX.
FAQ layout template:
resources/views/vendor/zeus/themes/zeus/sky/addons/faq.blade.php
Create and manage navigation menus.
Tips:
Note: The CMS feature is based on https://github.com/lara-zeus/sky. By default, the library and tag features are disabled, but you can enable them if needed (in AdminPanelProvider.php). Visit their documentation for more customization information.
The user dashboard interface is highly customizable through various Livewire components and blade views. SaaShovel automatically loads the appropriate views based on your configured billing provider.
Core dashboard files:
app\Livewire\page\dashboard\Dashboard.phpresources\views\livewire\pages\dashboard\dashboard.blade.php
Core subscription files:
app\Livewire\page\dashboard\ManageSubscription.php
resources\views\livewire\pages\dashboard\manage-subscription.blade.php
Located in
resources\views\livewire\pages\dashboard\partials\
lemonsqueezy-manage-subscription.blade.phplemonsqueezy-price-table.blade.phpnowpayments-manage-subscription.blade.phpnowpayments-price-table.blade.phppaddle-manage-subscription.blade.phppaddle-price-table.blade.phpstripe-manage-subscription.blade.phpstripe-price-table.blade.phpLocated in
resources\views\livewire\pages\landing-page\partials\
lemonsqueezy-price-table.blade.phpnowpayments-price-table.blade.phppaddle-price-table.blade.phpstripe-price-table.blade.php
Note: All views are automatically loaded based on
your BILLING_PROVIDER environment variable setting. No additional
configuration is required.
The AppServiceProvider (app/Providers/AppServiceProvider.php) handles core application configurations, including billing, themes, webhooks, and component registration.
Note: When modifying the AppServiceProvider, ensure to:
The authentication screens can be customized through the DevDojo Auth package setup interface at myapp.test/auth/setup. Full documentation available at DevDojo Auth Docs.
Note: The setup interface is automatically disabled in production environment.
Filament admin panel can be customized in app/Providers/Filament/AdminPanelProvider.php. Refer to Filament documentation for detailed customization options.
Cookie consent banner can be customized through:
The contact page can be managed through the Admin Panel's Contact tab:
Notes:
Create and manage FAQs through the Admin Panel's Site tab > FAQs sub-tab.
The FAQ view template is located at: resources/views/vendor/zeus/themes/zeus/sky/addons/faq.blade.php
Additional Resources:
This is a list of SaaShovel components that you can copy and paste to quickly build a landing page.
Since SaaShovel is built ontop of Jetstream, you can also use their components by referring to their documentation here.
All components are located in the folder:
resources/views/components/
You can customize each component by either using the attributes or modify the component's source code.
A responsive header component with navigation menu and user authentication options.
<x-header />
A prominent hero section typically used at the top of a landing page.
title: The main headline text.subtitle: A supporting subheadline text (supports
HTML).
ctaText: Text for the call-to-action button.ctaUrl: URL for the CTA button.titleColor: Color of the main headline (defaults to
theme setting).subtitleColor: Color of the subheadline (defaults to
theme setting).ctaBackgroundColor: Background color of the CTA
button
(defaults to theme setting).ctaTextColor: Text color of the CTA button (defaults
to
theme setting).ctaHoverBackgroundColor: Hover background color of
the
CTA button (defaults to theme setting).bgColor: Background color of the hero section
(defaults
to theme setting).
<x-hero-section
title="Welcome to Our Platform"
subtitle="The best solution for your business needs"
ctaText="Get Started"
ctaUrl="/signup"
>
<x-slot name="image">
<img src="{{ asset('logos/shovel.png') }}" alt="Hero Image">
</x-slot>
</x-hero-section>
A flexible modal component that can be used for various purposes such as alerts, confirmations, or forms.
id: Unique identifier for the modal (defaults to
'modal').maxWidth: Maximum width of the modal ('sm', 'md',
'lg',
'xl', '2xl') (defaults to '2xl').bgColor: Background color of the modal (defaults to
theme setting).textColor: Text color of the modal content (defaults
to
theme setting).overlayColor: Color of the modal overlay (defaults
to
theme setting).overlayOpacity: Opacity level of the overlay
(defaults
to theme setting).titleSize: Font size of the modal title (defaults to
'text-lg').titleWeight: Font weight of the title (defaults to
'font-medium').footerBgColor: Background color of the modal footer
(defaults to theme setting).confirmBtnBgColor: Background color of the confirm
button (defaults to theme setting).confirmBtnHoverBgColor: Hover background color of
the
confirm button (defaults to theme setting).confirmBtnTextColor: Text color of the confirm
button
(defaults to theme setting).cancelBtnBgColor: Background color of the cancel
button
(defaults to theme setting).cancelBtnHoverBgColor: Hover background color of the
cancel button (defaults to theme setting).cancelBtnTextColor: Text color of the cancel button
(defaults to theme setting).cancelBtnBorderColor: Border color of the cancel
button
(defaults to theme setting).
<x-custom-modal id="login-modal" maxWidth="md">
<x-slot name="title">
Login
</x-slot>
<x-slot name="content">
<!-- Login form content -->
<form class="space-y-4">
<div>
<label for="email" class="block text-sm font-medium text-gray-700">
Email
</label>
<input
type="email"
id="email"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm"
/>
</div>
<div>
<label for="password" class="block text-sm font-medium text-gray-700">
Password
</label>
<input
type="password"
id="password"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm"
/>
</div>
</form>
</x-slot>
<x-slot name="footer">
<button
type="button"
class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700"
@click="confirm"
>
Login
</button>
<button
type="button"
class="mr-3 bg-white text-gray-700 px-4 py-2 rounded-md border hover:bg-gray-50"
@click="close"
>
Cancel
</button>
</x-slot>
</x-custom-modal>
<button type="button" class="bg-blue-600 text-white px-4 py-2 rounded-md"
@click="$dispatch('open-modal', { title: 'Login to Your Account', confirmButtonText: 'Login', confirmAction: () =>
{ console.log('Login attempted'); return true; } })">
Open Modal
</button>
A section component that displays features in an interactive tabbed interface.
id: Unique identifier for the section.title: The main title of the section.description: A brief description of the features.
bgColor: Background color of the section (defaults
to
theme setting).titleColor: Color of the section title (defaults to
theme setting).descriptionColor: Color of the section description
(defaults to theme setting).tabTextColor: Color of the tab text (defaults to
theme
setting).activeTabIconColor: Color of the active tab icon
(defaults to theme setting).tabIconColor: Color of inactive tab icons (defaults
to
theme setting).name: The name of the tab.tabId: Unique identifier for the tab.icon: SVG content for the tab icon.mediaType: Type of media to display ('image' or
'video') (defaults to empty).mediaUrl: URL for the media content (defaults to
empty).title: Title of the tab content (defaults to empty).
description: Description text for the tab (defaults
to
empty).features: Array of feature points to display with
checkmarks (defaults to empty array).checkmarkColor: Color of the feature checkmark icons
(defaults to theme setting).
<x-interactive-features-section
id="features"
title="Unleash the potential of your SaaS"
description="Don't let technical debt bury your SaaS before it begins. SaaShovel provides the robust foundation you need - from user logins to payment processing. Construct your dream SaaS on solid ground and reach profitability faster."
>
<x-interactive-feature-tab
tabId="payments"
name="Payments"
icon='
<svg xmlns="http://www.w3.org/2000/svg" class="w-8 h-8 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m2 4h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z"/>
</svg>'
title="Multi-Payment Support"
description="Integrate multiple payment processors for business continuity and flexibility:"
:features="[
'<img src=\'{{ asset('logos/stripe.png') }}\' alt=\'Stripe\' class=\'inline mx-1\'><a class=\'font-bold\' href=\'https://stripe.com\' target=\'_blank\' rel=\'noopener noreferrer\'>Stripe</a>',
'<img src=\'{{ asset('logos/lemonsqueezy.png') }}\' alt=\'LemonSqueezy\' class=\'inline mx-1\'><a class=\'font-bold\' href=\'https://www.lemonsqueezy.com\' target=\'_blank\' rel=\'noopener noreferrer\'>LemonSqueezy</a>',
'<img src=\'{{ asset('logos/paddle.png') }}\' alt=\'Paddle\' class=\'inline mx-1\'><a class=\'font-bold\' href=\'https://paddle.com\' target=\'_blank\' rel=\'noopener noreferrer\'>Paddle</a>',
'<img src=\'{{ asset('logos/nowpayments.png') }}\' alt=\'NowPayments\' class=\'inline mx-1\'><a class=\'font-bold\' href=\'https://nowpayments.io\' target=\'_blank\' rel=\'noopener noreferrer\'>NowPayments</a> for crypto'
]"
>
<p class="mt-2">
Never worry about payment processor bans again.
</p>
</x-interactive-feature-tab>
<x-interactive-feature-tab
tabId="subscription"
name="Subscriptions"
mediaType="video"
mediaUrl='illustrations/subscription.mp4'
icon='
<svg xmlns="http://www.w3.org/2000/svg" class="w-8 h-8 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4V7a2 2 0 00-2-2H5z"/>
</svg>'
title="Effortless Subscription Journey"
description="Experience a smooth, end-to-end subscription process:"
:features="[
'One-click plan selection',
'Streamlined user registration',
'Webhook handling'
]"
>
</x-interactive-feature-tab>
<x-interactive-feature-tab
tabId="permissions"
name="Permissions"
mediaType="image"
mediaUrl='illustrations/permissions.png'
icon='
<svg xmlns="http://www.w3.org/2000/svg" class="w-8 h-8 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
</svg>'
title="Smooth Permission Handling"
description="Effortlessly manage user access with the powerful and flexible permission system:"
:features="[
'<b>@@can</b> and <b>@@cannot</b> directives to restrict access',
'<b>$user->can()</b> and <b>$user->cannot()</b> methods for granular control',
'Route <b>middlewares</b> to restrict access to specific subscriber tiers'
]"
>
</x-interactive-feature-tab>
</x-interactive-features-section>
Never worry about payment processor bans again.
A section component to showcase specific features with text and media.
showSections: Controls visibility of the sections
(defaults to false).id: Unique identifier for the section.title: The main title of the feature.description: A brief description of the feature.
mediaType: Type of media to display ('image',
'video',
'emoji') (defaults to 'image').mediaSrc: Source URL or content for the media
(defaults
to empty string).mediaPosition: Position of the media ('left' or
'right')
(defaults to 'right').bgColor: Background color of the section (defaults
to
theme setting).titleColor: Color of the title text (defaults to
theme
setting).descriptionColor: Color of the description text
(defaults to theme setting).listItemColor: Color of the list items (defaults to
theme setting).ctaText: Text for the call-to-action button
(defaults to
null).ctaUrl: URL for the call-to-action button (defaults
to
'#').ctaBgColor: Background color of the CTA button
(defaults
to theme setting).ctaTextColor: Text color of the CTA button
(defaults
to
theme setting).ctaHoverBgColor: Hover background color of the CTA
button (defaults to theme setting).
<x-features-section>
<x-feature
id="benefits"
title="Launch Your SaaS Faster"
description="Our starter-kit is designed to help you build and launch your SaaS product for a worldwide audience in record time. Focus on your unique features while we handle the details."
media-type="emoji"
media-src="💨"
media-position="right"
cta-text="Get Started"
cta-url="#"
>
<li>Multiple payment processors for business continuity</li>
<li>Crypto payments support for a wider audience</li>
<li>Built-in localization for global reach</li>
<li>CMS with flexible page permissions</li>
<li>Admin panel with Google Analytics integration</li>
<li>Modern auth screens with social provider support</li>
<li>Configurable features and components to fit your needs</li>
</x-feature>
</x-features-section>
A vertically oriented feature section component.
id: Unique identifier for the section.title: The main title of the feature.description: A brief description of the feature.
mediaType: Type of media to display ('video',
'image',
or 'emoji') (defaults to empty).mediaSrc: Source URL or content for the media
(defaults
to empty).bgColor: Background color of the section (defaults
to
theme setting).titleColor: Color of the title text (defaults to
theme
setting).descriptionColor: Color of the description text
(defaults to theme setting).listItemColor: Color of the list items (defaults to
theme setting).ctaText: Text for the call-to-action button
(defaults
to null).ctaUrl: URL for the CTA button (defaults to '#').
ctaBgColor: Background color of the CTA button
(defaults to theme setting).ctaTextColor: Text color of the CTA button
(defaults
to
theme setting).ctaHoverBgColor: Hover background color of the CTA
button (defaults to theme setting).
<x-vertical-feature-section
id="payment-gateways"
title="Flexible Payment Options"
description="SaaShovel supports multiple payment gateways, allowing you to easily bill your users through various methods and expand your payment capabilities."
>
<li class="list-none">
<div class="w-full my-7">
<a class="font-bold" href="https://paddle.com" target="_blank" rel="noopener noreferrer">
<img src="illustrations/paddle.png" alt="paddle" class="w-1/2 m-auto">
</a>
</div>
SaaShovel supports Paddle as a subscription payment gateway, allowing you to easily bill your users on a monthly, yearly, or per-seat basis. (Customer portal built-in)
</li>
<li class="list-none">
<div class="w-full my-7">
<a class="font-bold" href="https://stripe.com" target="_blank" rel="noopener noreferrer">
<img src="illustrations/stripe.png" alt="stripe" class="w-1/3 m-auto">
</a>
</div>
SaaShovel also offers support for Stripe as a subscription gateway, allowing for recurring payments, per-seat pricing, and much more. (Customer portal through Stripe)
</li>
<li class="list-none">
<div class="w-full my-7">
<a class="font-bold" href="https://lemonsqueezy.com" target="_blank" rel="noopener noreferrer">
<img src="illustrations/lemonsqueezy.png" alt="lemonsqueezy" class="w-1/2 m-auto">
</a>
</div>
SaaShovel integrates with LemonSqueezy, providing an additional payment processing option for your SaaS business. (Customer portal through LemonSqueezy)
</li>
<li class="list-none">
<div class="w-full my-7">
<a class="font-bold" href="https://nowpayments.io" target="_blank" rel="noopener noreferrer">
<img src="illustrations/nowpayments.png" alt="nowpayments" class="w-1/2 m-auto">
</a>
</div>
With NowPayments integration, SaaShovel allows you to accept cryptocurrency payments, expanding your customer base to crypto enthusiasts. (Customer portal built-in)
</li>
</x-vertical-feature-section>
A grid layout component for displaying multiple feature items.
title: The title of the features section (defaults
to
'Why Choose SaaShovel?').bgColor: Background color of the section (defaults
to
theme setting).titleColor: Color of the section title (defaults to
theme setting).gridCols: CSS classes for grid column layout
(defaults
to 'md:grid-cols-3').icon: SVG path for the feature icon.title: The title of the feature item.bgColor: Background color of the feature item
(defaults
to theme setting).iconColor: Color of the icon (defaults to theme
setting).titleColor: Color of the item title (defaults to
theme
setting).contentColor: Color of the item content (defaults
to
theme setting).
<x-features-grid title="Skip the foundation, start building your SaaS today">
<x-feature-item
icon='
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m2 4h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z">
</path>
'
title="Multi-Payment Support">
<p>Integrate multiple payment processors:</p>
<ul class="list-disc pl-5 mt-2">
<li>
<img src="http://saashovel.test/logos/stripe.png" alt="Stripe" class="inline mx-1">
<a class="font-bold" href="https://stripe.com" target="_blank" rel="noopener noreferrer">
Stripe
</a>
</li>
<li>
<img src="http://saashovel.test/logos/lemonsqueezy.png" alt="LemonSqueezy" class="inline mx-1">
<a class="font-bold" href="https://www.lemonsqueezy.com" target="_blank" rel="noopener noreferrer">
LemonSqueezy
</a>
</li>
<li>
<img src="http://saashovel.test/logos/paddle.png" alt="Paddle" class="inline mx-1">
<a class="font-bold" href="https://paddle.com" target="_blank" rel="noopener noreferrer">
Paddle
</a>
</li>
<li>
<img src="http://saashovel.test/logos/nowpayments.png" alt="NowPayments" class="inline mx-1">
<a class="font-bold" href="https://nowpayments.io" target="_blank" rel="noopener noreferrer">
NowPayments
</a>
for crypto
</li>
</ul>
<p class="mt-2">Never worry about payment processor bans again.</p>
</x-feature-item>
<x-feature-item
icon='
<rect x="2" y="3" width="20" height="14" rx="2" ry="2" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
</rect>
<line x1="2" y1="20" x2="22" y2="20" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
</line>
<line x1="6" y1="7" x2="18" y2="7" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
</line>
<line x1="6" y1="11" x2="14" y2="11" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
</line>
<line x1="6" y1="15" x2="10" y2="15" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
</line>
'
title="Built-in CMS">
<p>Create and manage content with ease. Set page permissions to restrict access to subscribers of specific tiers. Includes customizable contact page for customer interaction and a flexible FAQ section.</p>
</x-feature-item>
<x-feature-item
icon='
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z">
</path>
'
title="TALL Stack Powered">
<p>
Leverage the power of
<a class="font-bold text-lime-600 hover:underline" href="https://tailwindcss.com" target="_blank" rel="noopener noreferrer">
Tailwind
</a>,
<a class="font-bold text-lime-600 hover:underline" href="https://alpinejs.dev" target="_blank" rel="noopener noreferrer">
Alpine.js
</a>,
<a class="font-bold text-lime-600 hover:underline" href="https://laravel.com" target="_blank" rel="noopener noreferrer">
Laravel
</a>, and
<a class="font-bold text-lime-600 hover:underline" href="https://livewire.laravel.com" target="_blank" rel="noopener noreferrer">
Livewire
</a>
for a modern, reactive, and scalable application. As well as
<a class="font-bold text-lime-600 hover:underline" href="https://jetstream.laravel.com" target="_blank" rel="noopener noreferrer">
Jetstream
</a>
for user's account management and
<a class="font-bold text-lime-600 hover:underline" href="https://filamentphp.com" target="_blank" rel="noopener noreferrer">
Filament
</a>
for the admin panel.
</p>
</x-feature-item>
</x-features-grid>
Integrate multiple payment processors:
Stripe
LemonSqueezy
Paddle
NowPayments
for crypto
Never worry about payment processor bans again.
Create and manage content with ease. Set page permissions to restrict access to subscribers of specific tiers. Includes customizable contact page for customer interaction and a flexible FAQ section.
Leverage the power of Tailwind , Alpine.js , Laravel , and Livewire for a modern, reactive, and scalable application. As well as Jetstream for user's account management and Filament for the admin panel.
A section component to display multiple pricing plans.
plans: Array of pricing data (defaults to empty
array).pricingId: Unique identifier for the section
(defaults
to 'pricing').class: Additional CSS classes (defaults to
'py-10').
title: The title of the pricing section (defaults
to
'Pricing').bgColor: Background color of the section (defaults
to
theme setting).titleColor: Color of the section title (defaults to
theme setting).titleSize: Font size of the title (defaults to
'text-3xl').titleWeight: Font weight of the title (defaults to
'font-bold').titleAlignment: Text alignment of the title
(defaults
to 'text-center').titleMargin: Margin of the title (defaults to
'mb-8').
name: The name of the pricing plan.price: The price of the plan.features: Array of features included in the plan.
highlighted: Boolean to highlight this plan
(defaults
to false).ctaBtnText: Text for the main CTA button (defaults
to
'Get Started').ctaSmText: Small text below CTA button (defaults to
empty).ctaAction: URL for the CTA button (defaults to
'#').
wireClick: Livewire method to call on click.alpineClick: Alpine.js method to call on click.
planId: Unique identifier for the plan.showCtaBtn: Show/hide the CTA button (defaults to
true).showCryptoBtn: Show/hide the crypto payment button
(defaults to false).cryptoBtnText: Text for the crypto button (defaults
to
'Pay with Crypto').cryptoWireClick: Livewire method for crypto button.
cryptoAlpineClick: Alpine.js method for crypto
button.
cryptoPlanId: Unique identifier for crypto payment
plan.
<x-pricing-section title="Choose Your Plan">
<x-pricing-plan
name="Basic Plan"
price="$19/month"
:features="['Up to 10 users', 'Basic support', 'Basic analytics']"
ctaBtnText="Choose Plan"
/>
<x-pricing-plan
name="Advanced Plan"
price="$39/month"
:features="[
'Up to 50 users',
'Priority support',
'Advanced analytics',
'Custom integrations',
]"
highlighted="true"
ctaBtnText="Choose Plan"
/>
<x-pricing-plan
name="Pro Plan"
price="$99/month"
:features="[
'Unlimited users',
'24/7 support',
'Enterprise analytics',
'Custom development',
'Dedicated account manager',
]"
ctaBtnText="Choose Plan"
/>
</x-pricing-section>
A container component for grouping FAQ items.
title: The title of the FAQ section (defaults to
'Frequently Asked Questions').bgColor: Background color of the FAQ section
(defaults
to theme setting).titleColor: Color of the section title (defaults to
theme setting).question: The question text to be displayed.answer: The answer text to be displayed.questionClass: Styling classes for the question
text
(defaults to theme setting).answerClass: Styling classes for the answer text
(defaults to theme setting).borderClass: Styling classes for the item border
(defaults to theme setting).
<x-faq-section title="Common Questions">
<x-faq-item
question="What is your return policy?"
answer="Our return policy allows returns within 30 days of purchase."
/>
<x-faq-item
question="How do I contact support?"
answer="You can reach our support team through the contact form or email."
/>
</x-faq-section>
A flexible testimonial section that displays customer feedback in a responsive grid layout.
testimonials: Array of testimonial objects
containing quote, name, title (optional), and avatar (optional).sectionTitle: The section heading (defaults to
"Testimonials").bgColor: Background color of the section (defaults
to theme setting).cardBgColor: Background color of testimonial cards
(defaults to theme setting).titleColor: Color of the section title (defaults to
theme setting).quoteColor: Color of the testimonial text (defaults
to theme setting).authorNameColor: Color of author names (defaults to
theme setting).authorTitleColor: Color of author titles (defaults
to theme setting).titleSize: Font size of the section title (defaults
to 'text-3xl').titleWeight: Font weight of the section title
(defaults to 'font-bold').titleMargin: Margin for the section title (defaults
to 'mb-12').
<x-testimonial-section
section-title="What Our Customers Say"
:testimonials="[
[
'quote' => 'Amazing product that simplified our workflow.',
'name' => 'John Doe',
'title' => 'CEO at Company',
'avatar' => '/path/to/avatar.jpg'
],
[
'quote' => 'Best solution we\'ve found in the market.',
'name' => 'Jane Smith',
'title' => 'Product Manager',
'avatar' => '/path/to/avatar2.jpg'
]
]"
/>
The CTA Section component creates a full-width call-to-action section with customizable content and styling.
title: The main title of the CTA section.description: A brief description or subtitle.ctaText: The text for the call-to-action button.
ctaUrl: The URL for the CTA button.bgColor: Background color of the section (defaults
to
theme setting).imagePosition: Position of the image/video/svg
('left' or
'right', defaults to 'right').titleColor: Color of the title text (defaults to
theme
setting).titleSize: Font size of the title (defaults to
'text-3xl').titleWeight: Font weight of the title (defaults to
'font-bold').titleMargin: Margin spacing for the title (defaults
to
'mb-4').descriptionColor: Color of the description text
(defaults
to theme setting).descriptionSize: Font size of the description
(defaults
to 'text-xl').descriptionMargin: Margin spacing for the
description
(defaults to 'mb-6').ctaBgColor: Background color of the CTA button
(defaults
to theme setting).ctaTextColor: Text color of the CTA button
(defaults to
theme setting).ctaHoverBgColor: Background color of the CTA button
on
hover (defaults to theme setting).ctaFontWeight: Font weight of the CTA button text
(defaults to 'font-semibold').ctaRounded: Border radius of the CTA button
(defaults to
'rounded-md').ctaPadding: Padding of the CTA button (defaults to
'px-6
py-3').ctaTransition: Transition effect for the CTA button
(defaults to 'transition duration-300').sectionPadding: Padding for the entire section
(defaults
to 'sm:py-12 md:py-16 py-5').containerMaxWidth: Maximum width of the container
(defaults to 'max-w-7xl').imageSpacing: Spacing between the content and image
(defaults to 'md:pl-8').
<x-cta-section
title="Join Our Newsletter"
description="Stay updated with our latest news and offers"
ctaText="Subscribe Now"
ctaUrl="/subscribe"
bgColor="bg-gray-100"
/>
Saashovel offers two methods for creating pages:
Create pages through the Filament admin panel's CMS. This method provides a user-friendly interface with a built-in permission system to restrict page access based on subscription tiers.
Tip: The CMS method is recommended for
content-focused pages where you need simple subscription-based access control.
Note: The main page template for pages created
via CMS can be customized at:
resources/views/vendor/zeus/themes/zeus/sky/page.blade.php
Create custom page components using the saashovel:page command for more
complex functionality.
This command generates:
app/Livewire/Page/{Name}/{Name}.phpresources/views/livewire/pages/{name}/{name}.blade.php
Use the following middleware to restrict access based on subscription tiers:
// this route will only be accessible to users with a subscription
Route::get('/your-route-name', YourRouteNameComponent::class)
->middleware(EnsureUserIsSubscribed::class);
// first tier subscribers and above
Route::get('/first-tier-route', FirstTierComponent::class)
->middleware(EnsureUserIsSubscribedToFirstTier::class);
// second tier subscribers and above
Route::get('/second-tier-route', SecondTierComponent::class)
->middleware(EnsureUserIsSubscribedToSecondTier::class);
// third tier subscribers only
Route::get('/third-tier-route', ThirdTierComponent::class)
->middleware(EnsureUserIsSubscribedToThirdTier::class);
Saashovel provides two methods for managing JavaScript assets:
For static JavaScript files, use Laravel's standard asset management:
resources/js/resources/js/app.jsBest Practice: Use traditional asset management for static JavaScript files that don't require dynamic Blade variables.
For JavaScript that requires Blade variables or dynamic content:
resources/views/livewire/pages/assets/resources/views/livewire/pages/assets/default-merged-assets.blade.php,
resources/views/livewire/pages/assets/merged-assets.blade.phpImportant: The default-merged-assets file contains essential code for subscription management. Do not modify it, to add your own assets, do it in the merged-assets file.
The merged assets files are included in both app and guest layouts:
@@include('livewire.pages.assets.default-merged-assets')
@@include('livewire.pages.assets.merged-assets')
To add dynamic assets:
resources/views/livewire/pages/assets/
{{-- Add your own assets as needed below. --}}
@@include('livewire.pages.assets.your-custom-asset')
Best Practice: Always prefer traditional asset management unless you specifically need Blade functionality in your JavaScript code.
The application dynamically displays either the home page or the landing page depending on the user's authentication status:
resources/views/livewire/pages/home/home.blade.php
resources/views/livewire/pages/landing-page/landing-page.blade.php
Both the home and landing pages share the same component:
app/Livewire/Page/Home/Home.php. This component checks the user's
authentication status and loads the appropriate view.
SaaShovel includes a robust permission system to control access to different features based on user roles and subscription tiers.
| Permission | Access Level |
|---|---|
public
|
Anyone can access |
access admin
panel |
Administrators only |
access basic
features |
Registered users without subscription |
access premium
features |
Any subscribed user |
access first
tier features |
First tier subscribers and above |
access second
tier features |
Second tier subscribers and above |
access third
tier features |
Third tier subscribers only |
| Role | Assigned Permissions |
|---|---|
admin
|
access admin panel, access basic features, access premium features, access first tier features, access second tier features, access third tier features |
user
|
access basic features |
premium-first-tier |
access basic features, access premium features, access first tier features |
premium-second-tier |
access basic features, access premium features, access first tier features, access second tier features |
premium-third-tier |
access basic features, access premium features, access first tier features, access second tier features, access third tier features |
Role Assignment: Upon registration, users are automatically assigned the "user" role with basic feature access. When subscribing to a plan, their role is upgraded to the corresponding tier role (first, second, or third tier). Users can only have one role at a time, though each role may grant multiple permissions.
@@can('access second tier features')
This is restricted to second-tier and above subscribers.
@@endcan
@@if (auth()->user()->can('access basic features'))
Only users who are registered but not subscribed will see this.
@@endif
if (Auth::user()->can('access second tier features')) {
'Only users who are subscribed to the second tier or higher will access this.'
}
// this route will only be accessible to users with a subscription
Route::get('/your-route-name', YourRouteNameComponent::class)
->middleware(EnsureUserIsSubscribed::class);
// first tier subscribers and above
Route::get('/first-tier-route', FirstTierComponent::class)
->middleware(EnsureUserIsSubscribedToFirstTier::class);
// second tier subscribers and above
Route::get('/second-tier-route', SecondTierComponent::class)
->middleware(EnsureUserIsSubscribedToSecondTier::class);
// third tier subscribers only
Route::get('/third-tier-route', ThirdTierComponent::class)
->middleware(EnsureUserIsSubscribedToThirdTier::class);
Pro Tip: Permissions are automatically managed based on user subscriptions. When a user upgrades or downgrades their subscription, their permissions are updated accordingly.
Security Note: Always combine frontend permission checks with backend middleware to ensure proper security. Frontend checks are for UI purposes only.
Thanks to Laravel's database abstraction layer, Saashovel supports multiple database systems out of the box:
mysql (Default)pgsql (PostgreSQL)sqlite (SQLite)sqlsrv (SQL Server)SaaShovel comes with pre-configured database seeds that set up your application with default roles, permissions, navigation menus, and test users.
| Role | Assigned Permissions |
|---|---|
| admin | All permissions |
| user | access basic features |
| premium-first-tier | access basic features, premium features, first tier features |
| premium-second-tier | access basic features, premium features, first & second tier features |
| premium-third-tier | access basic features, premium features, all tier features |
| Role | Password | |
|---|---|---|
| admin | admin@admin.com | admin@admin.com |
| user | user@user.com | user@user.com |
| Name | Handle | Menu Items |
|---|---|---|
| main | main | Contact (/contact), Features (/#features), Pricing (/#pricing) |
Pro Tips:
Important Notes:
SaaShovel includes a flexible theming system that allows you to customize the entire look of your application. Themes are configured in config/themes.php and can be switched using the APP_THEME environment variable.
APP_THEME=light
Default light mode with clean, professional styling
APP_THEME=dark
Dark mode optimized for low-light environments
APP_THEME=sunset
Warm and inviting theme with orange and rose accents
APP_THEME=nature
Organic feel with emerald greens and amber accents
Themes are organized by components, each with their own customizable properties:
Add your own theme by extending the themes configuration:
// config/themes.php
'custom-theme' => [
'global' => [
'bgColor' => 'bg-blue-50',
'textColor' => 'text-blue-900',
'accentColor' => 'text-blue-600',
// ... other global settings
],
'header' => [
'bgColor' => 'bg-white',
'menuLinkClass' => 'text-blue-600 hover:text-blue-700',
// ... component specific settings
],
// ... other component configurations
],
Then activate it by setting:
Pro Tip: All color classes are based on Tailwind CSS. You can use any Tailwind color utility class in your custom theme configuration.
Note: After modifying theme configurations,
remember to clear your application cache:
php artisan config:clear
Essential security configurations in your .env file:
APP_ENV=production
APP_DEBUG=false
SESSION_SECURE_COOKIE=true
SESSION_SAME_SITE=lax
Laravel and Livewire automatically handle CSRF protection. Every form should include the @csrf directive:
Blade automatically escapes content. For raw HTML, use with caution:
@{{ $escapedContent }}
@{!! $rawContent !!}
Protect sensitive properties using:
#[Locked]
public $sensitiveData; // Cannot be modified from frontend
protected $queryString = ['search' => ['except' => '']]; // URL parameters
// Validate component actions
public function save()
{
$this->validate([
'email' => 'required|email',
'password' => 'required|min:8'
]);
}
Security Best Practices:
The application uses Laravel Sanctum for API authentication and session-based auth for web routes.
Tip: Use middleware groups to protect routes:
Route::middleware(['auth:sanctum', 'verified'])->group(...)
The application verifies webhook signatures for all payment providers (Stripe, Paddle, LemonSqueezy, NOWPayments). This ensures that only legitimate requests from the payment providers are processed:
Important:
Secure file upload handling:
// Validate file uploads
'document' => ['required', 'file', 'mimes:pdf,docx', 'max:10240']
// Store in private disk
Storage::disk('private')->put($path, $file, 'private')
Note: Regular security updates and audits are
crucial. Use:
composer audit
to check for known vulnerabilities in your dependencies.