Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions database/seeders/BlogDatabaseSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function run(): void
'published_at' => now()->subMonths(5),
'category_id' => $gettingStarted->id,
'author_id' => $author?->id,
], public_path('images/blog/what-is-saucebase.jpg'));
], public_path('modules/blog/images/what-is-saucebase.jpg'));

$this->createPost([
'title' => 'Stop Rebuilding the Same Boilerplate Every Project',
Expand All @@ -48,7 +48,7 @@ public function run(): void
'published_at' => now()->subMonths(3),
'category_id' => $devExperience->id,
'author_id' => $author?->id,
], public_path('images/blog/tech-stack.jpg'));
], public_path('modules/blog/images/tech-stack.jpg'));

$this->createPost([
'title' => 'Your First Module: Scaffold and Ship in Under 10 Minutes',
Expand All @@ -58,7 +58,7 @@ public function run(): void
'published_at' => now()->subMonths(2),
'category_id' => $featuresModules->id,
'author_id' => $author?->id,
], public_path('images/blog/add-your-saucebase.jpg'));
], public_path('modules/blog/images/add-your-saucebase.jpg'));

$this->createPost([
'title' => 'Auth, Billing, and Privacy: The Three Modules Every SaaS Needs',
Expand All @@ -68,7 +68,7 @@ public function run(): void
'published_at' => now()->subMonth(),
'category_id' => $featuresModules->id,
'author_id' => $author?->id,
], public_path('images/blog/cookies-or-privacy.jpg'));
], public_path('modules/blog/images/cookies-or-privacy.jpg'));

$this->createPost([
'title' => 'Copy-and-Own: The Philosophy Behind Saucebase Modules',
Expand All @@ -78,7 +78,17 @@ public function run(): void
'published_at' => now()->subWeeks(2),
'category_id' => $devExperience->id,
'author_id' => $author?->id,
], public_path('images/blog/your-recipes.jpg'));
], public_path('modules/blog/images/your-recipes.jpg'));

$this->createPost([
'title' => 'Vue or React? What about both!',
'excerpt' => 'Choosing a frontend framework used to mean committing to a stack for the life of your project. Saucebase 2.0 changes that — ship with Vue 3 or React 19, and every module works either way.',
'content' => $content('post-7-vue-and-react.html'),
'status' => PostStatus::Published,
'published_at' => now()->subDays(3),
'category_id' => $devExperience->id,
'author_id' => $author?->id,
], public_path('modules/blog/images/vue-and-react.jpg'));
}

private function createPost(array $data, string $coverImage = ''): Post
Expand Down
30 changes: 30 additions & 0 deletions database/seeders/content/post-7-vue-and-react.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<p>Choosing a frontend framework used to mean committing to a stack for the life of your project. Pick Vue, and every module you install needs to be Vue. Pick React, and you're locked into that ecosystem. For a starter kit that ships with authentication, billing, settings, and a blog out of the box, that's a real constraint.</p>

<p>Saucebase 2.0 removes it.</p>

<h2>Both frameworks, fully supported</h2>

<p>Every Saucebase module ships with both a Vue 3 and a React 19 implementation. When you set up a new project, you choose your framework — and every module you install just works with it. No adapters, no workarounds, no "Vue only" footnotes in the docs.</p>

<p>Under the hood, each module keeps its framework implementations in <code>resources/js/vue/</code> and <code>resources/js/react/</code>. The module installer reads your project's <code>frontend.json</code> and copies the right files into place automatically.</p>

<h2>How switching works</h2>

<p>For contributors and teams evaluating the framework decision, Saucebase ships a command that makes switching non-destructive:</p>

<pre><code>php artisan saucebase:stack vue --dev
php artisan saucebase:stack react --dev</code></pre>

<p>In <code>--dev</code> mode, both framework directories are kept on disk. Entry points are thin passthroughs. You can flip between them without losing any work.</p>

<h2>The shared foundation</h2>

<p>Framework-specific code only lives where it has to. Routing, backend logic, Filament admin panels, database migrations, API endpoints — all of that is shared. The only thing that differs between the Vue and React versions of a module is the frontend layer.</p>

<p>This means a bug fix in a controller, a new field on a model, or a Filament resource change is written once and works for everyone regardless of their chosen framework.</p>

<h2>Why this matters for a starter kit</h2>

<p>A starter kit's job is to get out of your way. Locking you into a framework decision on day one — before you've written a single line of product code — is the opposite of that. Saucebase 2.0 lets you start building and figure out the rest later. Or never figure it out at all, because both options keep working.</p>

<p><strong>Pick the framework your team knows. Saucebase handles the rest.</strong></p>
Binary file added resources/assets/images/add-your-saucebase.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/assets/images/cookies-or-privacy.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/assets/images/tech-stack.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/assets/images/vue-and-react.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/assets/images/what-is-saucebase.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/assets/images/your-recipes.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/Http/Controllers/BlogController.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function show(string $categoryOrSlug, ?string $slug = null): Response
$category = Category::where('slug', $categoryOrSlug)->firstOrFail();
$post = $query->where('category_id', $category->id)->where('slug', $slug)->firstOrFail();
} else {
$post = $query->where('slug', $categoryOrSlug)->whereNull('category_id')->firstOrFail();
$post = $query->where('slug', $categoryOrSlug)->firstOrFail();
}

$related = Post::published()
Expand Down
Loading