<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[CRUDBooster's Substack]]></title><description><![CDATA[Accelerate Laravel Development! CRUDBooster: The Ultimate Admin Panel & CRUD Builder for Developers. 🚀]]></description><link>https://crudbooster.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!vmQt!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee0c6c09-25a4-46a0-9b73-f4f6b17a0c2a_1080x1080.png</url><title>CRUDBooster&apos;s Substack</title><link>https://crudbooster.substack.com</link></image><generator>Substack</generator><lastBuildDate>Sun, 10 May 2026 12:59:03 GMT</lastBuildDate><atom:link href="https://crudbooster.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Ferry Ariawan]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[crudbooster@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[crudbooster@substack.com]]></itunes:email><itunes:name><![CDATA[Ferry Ariawan]]></itunes:name></itunes:owner><itunes:author><![CDATA[Ferry Ariawan]]></itunes:author><googleplay:owner><![CDATA[crudbooster@substack.com]]></googleplay:owner><googleplay:email><![CDATA[crudbooster@substack.com]]></googleplay:email><googleplay:author><![CDATA[Ferry Ariawan]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Build a Custom Input Types in CRUDBooster]]></title><description><![CDATA[Build a Custom Color Input Type in CRUDBooster]]></description><link>https://crudbooster.substack.com/p/build-a-custom-input-types-in-crudbooster</link><guid isPermaLink="false">https://crudbooster.substack.com/p/build-a-custom-input-types-in-crudbooster</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Mon, 20 Oct 2025 23:53:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qZ_6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qZ_6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qZ_6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png 424w, https://substackcdn.com/image/fetch/$s_!qZ_6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png 848w, https://substackcdn.com/image/fetch/$s_!qZ_6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png 1272w, https://substackcdn.com/image/fetch/$s_!qZ_6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qZ_6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png" width="1456" height="809" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:809,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1582714,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/176659728?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qZ_6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png 424w, https://substackcdn.com/image/fetch/$s_!qZ_6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png 848w, https://substackcdn.com/image/fetch/$s_!qZ_6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png 1272w, https://substackcdn.com/image/fetch/$s_!qZ_6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e884799-f974-4ca5-a5c7-792ff0a83338_2056x1142.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Build a Custom Color Input Type in CRUDBooster</strong></h2><p>Sometimes you need a field that feels tailor&#8209;made &#8212; like a color picker for brand guidelines, themes, or status indicators. CRUDBooster supports custom input types with a clean, predictable structure. In this article, we&#8217;ll build `custom-color` that&#8217;s consistent, maintainable, and production&#8209;ready.</p><p>The goal isn&#8217;t just &#8220;it works&#8221;, but &#8220;it&#8217;s worth using&#8221;: consistent code, easy maintenance, and aligned with CRUDBooster patterns.</p><h2><strong>Prerequisites</strong></h2><p>- PHP `8.2+`</p><p>- Laravel `11.x` or `12.x`</p><p>- CRUDBooster installed and running</p><p>- Familiarity with Livewire, Blade, and Service Providers</p><p><strong>Why this matters:</strong></p><p>- PHP/Laravel versions affect syntax, lifecycle, and package compatibility.</p><p>- CRUDBooster must be active so the registrar and theme can discover your type.</p><p>- Livewire and Blade are the foundation for rendering and data binding in CRUDBooster forms.</p><p><strong>Practical tip:</strong></p><p>- Store custom types under `app/Cb/Types`. It cleanly separates types from modules, makes discovery easier, and keeps a tidy architecture.</p><h2><strong>What We&#8217;ll Build</strong></h2><p>We&#8217;ll create a color input type `custom-color` that provides:</p><p>- A form template rendering a native, lightweight color picker.</p><p>- A view template for detail/read&#8209;only pages with a small swatch.</p><p>- An option class to manage defaults and small reusable behaviors.</p><p>- A service provider to register the type with an explicit alias.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><h2><strong>Folder &amp; File Structure</strong></h2><p>This structure ensures CRUDBooster can discover and render the type.</p><p><code>app/Cb/Types/Color</code></p><p><code>|</code></p><p><code>&#9500;&#9472;&#9472; Function</code></p><p><code>&#9474; &#9472;&#9472; Color.php</code></p><p><code>&#9500;&#9472;&#9472; views</code></p><p><code>&#9474; &#9472;&#9472; form.blade.php</code></p><p><code>&#9474; &#9472;&#9472; view.blade.php</code></p><p><code>&#9492;&#9472;&#9472; ColorServiceProvider.php</code></p><p></p><p><strong>File roles:</strong></p><p>- `Function/Color.php`: option class for reusable settings (e.g., default color, preview toggle).</p><p>- `views/form.blade.php`: the form template (with Livewire binding and minimal a11y).</p><p>- `views/view.blade.php`: the read&#8209;only/detail template so users see a swatch and the value.</p><p>- `ColorServiceProvider.php`: registers the view alias and the type with the CRUDBooster registrar.</p><p>Best practices:</p><p>- Use a clear, consistent alias (`custom-color`) so it&#8217;s easy to reference.</p><p>- Keep options in `Function/Color.php` so Form builder usage stays clean.</p><h2><strong>Register the Type (Service Provider)</strong></h2><p>The provider ties everything together: it loads views, registers the type, and (optionally) adds assets.</p><p><code>&lt;?php</code></p><p><code>// File: app/Cb/Types/Color/ColorServiceProvider.php</code></p><p><code>namespace App\Cb\Types\Color;</code></p><p><code>use Illuminate\Support\ServiceProvider;</code></p><p><code>use CrudBooster\Components\Type\CBTypeRegistrar;</code></p><p><code>class ColorServiceProvider extends ServiceProvider</code></p><p><code>{</code></p><p><code>public function boot(): void</code></p><p><code> {</code></p><p><code>// Register Blade views under the alias `custom-color`</code></p><p><code>$this-&gt;loadViewsFrom(__DIR__.&#8217;/views&#8217;, &#8216;custom-color&#8217;);</code></p><p><code>// Register the type with CRUDBooster (color fits the text group)</code></p><p><code>CBTypeRegistrar::addText([</code></p><p><code>&#8216;type&#8217; =&gt; &#8216;custom-color&#8217;, // type name</code></p><p><code>&#8216;form&#8217; =&gt; &#8216;custom-color::form&#8217;, // form view alias</code></p><p><code>&#8216;view&#8217; =&gt; &#8216;custom-color::view&#8217;, // read-only view alias</code></p><p><code>&#8216;clazz&#8217; =&gt; Function\Color::class, // option class</code></p><p><code>&#8216;generalOption&#8217; =&gt; true, // enable built-in general options</code></p><p><code> ]);</code></p><p><code> }</code></p><p><code>}</code></p><p></p><p>Then register the provider so Laravel includes it:</p><p><code>&lt;?php</code></p><p><code>// File: app/Providers/AppServiceProvider.php</code></p><p><code>namespace App\Providers;</code></p><p><code>use Illuminate\Support\ServiceProvider;</code></p><p><code>use App\Cb\Types\Color\ColorServiceProvider;</code></p><p><code>class AppServiceProvider extends ServiceProvider</code></p><p><code>{</code></p><p><code>public function register(): void</code></p><p><code> {</code></p><p><code>$this-&gt;app-&gt;register(ColorServiceProvider::class);</code></p><p><code> }</code></p><p><code>}</code></p><p></p><p>Key notes:</p><p>- `loadViewsFrom` exposes a namespace alias used by the registrar in `form` and `view`.</p><p>- `CBTypeRegistrar::addText` places the type in the correct group (text&#8209;like), which matters for UI integration and default behavior.</p><p>- `generalOption =&gt; true` unlocks CRUDBooster&#8217;s built&#8209;in input transformations from the module builder.</p><h2><strong>Type Groups You Can Use</strong></h2><p>Choose the right registrar to match UI/behavior expectations:</p><p>- `addText` &#8212; text&#8209;like inputs (we use this for color)</p><p>- `addDateTime` &#8212; date &amp; time inputs</p><p>- `addWysiwyg` &#8212; rich text editor</p><p>- `addNumeric` &#8212; numeric (number, money, decimal) with formatting</p><p>- `addUpload` &#8212; file/image upload</p><p>- `addPassword` &#8212; password fields with safe behavior</p><p>- `addJson` &#8212; structured JSON input</p><p>- `addSelect` &#8212; choices (select, radio, checkbox)</p><p>- `addMap` &#8212; maps and coordinates</p><p>How to choose:</p><p>- Consider how the value is stored (string vs numeric vs JSON) and how built&#8209;in UI behaves.</p><p>- Pick the group that best matches the base behavior of your type so defaults stay relevant.</p><h2><strong>General Options (Built&#8209;ins)</strong></h2><p>With `&#8217;generalOption&#8217; =&gt; true`, you can use helpful transformations from the module builder:</p><p>- `uppercase`, `lowercase`, `noSpace`, `noSpecialChar`</p><p>- `numeric`, `nonNumeric`, `numberFormat`, `phoneFormat`</p><p>Context for color:</p><p>- Colors are typically hex strings (`#RRGGBB`). Avoid `numeric/nonNumeric` for this use case.</p><p>- `noSpace` or `noSpecialChar` is irrelevant with native `&lt;input type=&#8221;color&#8221;&gt;`, but useful if you fall back to a manual text input.</p><h2><strong>Form Template (Blade)</strong></h2><p>The form template defines how the input is rendered and bound to Livewire. Keep accessibility (labels, focus) and responsiveness in mind.</p><p><code>{{-- File: app/Cb/Types/Color/views/form.blade.php --}}</code></p><p><code>{{-- The $column variable contains key, placeholder, label, helpText, etc. --}}</code></p><p><code>&lt;input type=&#8221;color&#8221;</code></p><p><code>id=&#8221;{{$column[&#8217;key&#8217;]}}&#8221;</code></p><p><code>{{ $focus ? &#8216;autofocus&#8217; : &#8216;&#8217; }}</code></p><p><code>placeholder=&#8221;{{$column[&#8217;placeholder&#8217;] ?? &#8216;&#8217;}}&#8221;</code></p><p><code>@readonly($column[&#8217;readonly&#8217;] ?? false)</code></p><p><code>wire:loading.attr=&#8221;readonly&#8221;</code></p><p><code>wire:target=&#8221;formSave&#8221;</code></p><p><code>@if(isset($column[&#8217;live&#8217;]))</code></p><p><code>wire:model.live.debounce.{{$column[&#8217;live&#8217;]}}ms=&#8221;formData.{{$column[&#8217;key&#8217;]}}&#8221;</code></p><p><code>@else</code></p><p><code>wire:model=&#8221;formData.{{$column[&#8217;key&#8217;]}}&#8221;</code></p><p><code>@endif</code></p><p><code>class=&#8221;form-control&#8221;&gt;</code></p><p></p><p>Binding details:</p><p>- `wire:model` binds the value to `formData[key]` so CRUDBooster manages form state.</p><p>- `wire:loading.attr=&#8221;readonly&#8221;` prevents changes while submitting.</p><p>- `autofocus` improves UX when the field is important.</p><p>Optional extras:</p><p>- Render the label and helpText from `$column` outside the input to improve accessibility.</p><p>- Use `debounce` if color changes trigger heavy preview updates.</p><h2><strong>View Template (Blade)</strong></h2><p>The view template shows the saved value on detail/read&#8209;only pages. A small swatch helps with quick visual verification.</p><p><code>{{-- File: app/Cb/Types/Color/views/view.blade.php --}}</code></p><p><code>{{-- Available: $column, $value, $formData --}}</code></p><p><code>@php</code></p><p><code>$color = $value ?? ($column[&#8217;option&#8217;][&#8217;default&#8217;] ?? &#8216;#000000&#8217;);</code></p><p><code>@endphp</code></p><p><code>&lt;span style=&#8221;display:inline-block;width:16px;height:16px;background-color:{{ $color }};border:1px solid #ddd;border-radius:3px;margin-right:8px;&#8221;&gt;&lt;/span&gt;</code></p><p><code>&lt;code&gt;{{ $color }}&lt;/code&gt;</code></p><p></p><p>Display tips:</p><p>- Keep the swatch small so it doesn&#8217;t disrupt layout.</p><p>- Show the color code for easy copying.</p><p>- Provide a fallback like `#000000` when the value is missing.</p><h2><strong>Type Option Class</strong></h2><p>Options make configuration reusable and clean when using the Form builder.</p><p><code>&lt;?php</code></p><p><code>// File: app/Cb/Types/Color/Function/Color.php</code></p><p><code>namespace App\Cb\Types\Color\Function;</code></p><p><code>use CrudBooster\Components\Type\TypeOptionAbstract;</code></p><p><code>class Color extends TypeOptionAbstract</code></p><p><code>{</code></p><p><code>/**</code></p><p><code> * Set a default color (hex), e.g., #FF6B6B</code></p><p><code> */</code></p><p><code>public function default(string $hex): static</code></p><p><code> {</code></p><p><code>$this-&gt;option[&#8217;default&#8217;] = $hex;</code></p><p><code>return $this;</code></p><p><code> }</code></p><p><code>/**</code></p><p><code> * Show or hide the preview swatch in the form</code></p><p><code> */</code></p><p><code>public function showPreview(bool $show): static</code></p><p><code> {</code></p><p><code>$this-&gt;option[&#8217;showPreview&#8217;] = $show;</code></p><p><code>return $this;</code></p><p><code> }</code></p><p><code>}</code></p><p></p><p>Option best practices:</p><p>- Validate hex values at the form layer if needed (e.g., Laravel rules) to keep data safe.</p><p>- Keep options chainable: `Color::option()-&gt;default(&#8217;#FF6B6B&#8217;)-&gt;showPreview(true)`.</p><h2><strong>Adding CSS &amp; JS Assets (Optional)</strong></h2><p>Need richer features (palettes, sampling, alpha)? Register CSS/JS assets &#8212; they&#8217;re automatically injected into the CRUDBooster theme header.</p><p><code>&lt;?php</code></p><p><code>// Inside: app/Cb/Types/Color/ColorServiceProvider.php</code></p><p><code>use CrudBooster\Themes\CbThemeAssetRegistrar;</code></p><p><code>CbThemeAssetRegistrar::addCss(&#8217;https://example.com/color-picker.css&#8217;);</code></p><p><code>CbThemeAssetRegistrar::addJs(&#8217;https://example.com/color-picker.js&#8217;);</code></p><p></p><p>Notes:</p><p>- Ensure assets aren&#8217;t too heavy to keep the admin panel snappy.</p><p>- Consider self&#8209;hosting assets if CDN access is unreliable in your environment.</p><h2><strong>Use It in a Form</strong></h2><p>Here&#8217;s a realistic usage in a Form Component &#8212; perfect for theme or branding settings.</p><p><code>&lt;?php</code></p><p><code>use CrudBooster\Livewire\FormBuilder\Form;</code></p><p><code>use App\Cb\Types\Color\Function\Color;</code></p><p><code>class ThemeForm extends \CrudBooster\Livewire\BaseFormComponent</code></p><p><code>{</code></p><p><code>public function init(): void</code></p><p><code> {</code></p><p><code>$this-&gt;makeForm([</code></p><p><code>Form::add(label: &#8216;Brand Color&#8217;, key: &#8216;brand_color&#8217;, type: &#8216;custom-color&#8217;)</code></p><p><code>-&gt;option(Color::option()-&gt;default(&#8217;#FF6B6B&#8217;)-&gt;showPreview(true)),</code></p><p><code> ]);</code></p><p><code> }</code></p><p><code>}</code></p><p></p><p>Database suggestions:</p><p>- Store as `VARCHAR(7)` for hex `#RRGGBB`, or `VARCHAR(9)` if you support alpha `#RRGGBBAA`.</p><p>- Use a migration default if you want an initial value when records are created.</p><h2><strong>Workflow at a Glance</strong></h2><p>- Create the folder structure and files.</p><p>- Write lightweight, accessible form and view templates.</p><p>- Add an option class under `Function` for reusable configuration.</p><p>- Register the service provider and call `CBTypeRegistrar` for the right group.</p><p>- (Optional) Add CSS/JS assets for advanced pickers.</p><p>- Use `Form::add` with your type name and chain options.</p><p>- Test in a real module and watch UX and data consistency.</p><p></p><h2><strong>Tips That Save Time</strong></h2><p>- Keep `type` names, view aliases, and class names consistent.</p><p>- Use a short, clear alias with `loadViewsFrom` (e.g., `custom-color`).</p><p>- Enable `generalOption` only if it&#8217;s relevant to your input behavior.</p><p>- Keep types under `app/Cb/Types` for a clean separation from modules.</p><h2><strong>Troubleshooting</strong></h2><p>- Type not recognized: ensure the service provider is registered and `CBTypeRegistrar` is called.</p><p>- View not found: check your `loadViewsFrom` alias matches the registrar config.</p><p>- Options not applied: make sure your option class extends `TypeOptionAbstract` and the template uses `$column[&#8217;option&#8217;]`.</p><p>- Livewire not updating: verify `wire:model` targets `formData[key]` and there are no binding errors.</p><p>- CSS/JS not loading: verify URLs/access and ensure `CbThemeAssetRegistrar::addCss/addJs` is called.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/p/build-a-custom-input-types-in-crudbooster?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/p/build-a-custom-input-types-in-crudbooster?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://crudbooster.substack.com/p/build-a-custom-input-types-in-crudbooster?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[Intercepting Data Before and After Saving in CRUDBooster]]></title><description><![CDATA[Hey everyone! If you've ever worked with admin panels, you know that sometimes you need to run custom logic right when a user saves a form.]]></description><link>https://crudbooster.substack.com/p/intercepting-data-before-and-after</link><guid isPermaLink="false">https://crudbooster.substack.com/p/intercepting-data-before-and-after</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Mon, 18 Aug 2025 08:40:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!AeCc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AeCc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AeCc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png 424w, https://substackcdn.com/image/fetch/$s_!AeCc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png 848w, https://substackcdn.com/image/fetch/$s_!AeCc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png 1272w, https://substackcdn.com/image/fetch/$s_!AeCc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AeCc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png" width="1456" height="813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:813,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1603385,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/171251538?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AeCc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png 424w, https://substackcdn.com/image/fetch/$s_!AeCc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png 848w, https://substackcdn.com/image/fetch/$s_!AeCc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png 1272w, https://substackcdn.com/image/fetch/$s_!AeCc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fe8d56b-532b-4dbd-a63f-73b9b066394e_2060x1150.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Hey everyone! If you've ever worked with admin panels, you know that sometimes you need to run custom logic right when a user saves a form. Maybe you need to generate a unique slug, send a notification, or log an action to an audit trail. Hacking the core logic is messy and a big no-no.</p><p>Luckily, CRUDBooster gives us a super clean way to hook into the form-saving process using simple event attributes. Today, we'll dive into two of the most useful ones: <code>#[OnFormSaving]</code> and <code>#[OnFormSaved]</code>. Let's get into it!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3>What You'll Need</h3><p>Before we start, you just need one thing:</p><ul><li><p>A CRUDBooster module that you've already created. We'll be working inside the <strong>Form Component</strong> file for that module (e.g., <code>app/Cb/Modules/YourModule/Livewire/YourModuleForm.php</code>).</p></li></ul><p>That's it! No complex setup required.</p><div><hr></div><h3>Running Code <em>Before</em> Data Hits the Database with <code>#[OnFormSaving]</code></h3><p>The <code>#[OnFormSaving]</code> attribute is your go-to when you need to do something <em>before</em> the data is written to your database. This is the perfect place for last-minute data validation, modification, or preparation.</p><h4>How to Use It</h4><p>Inside your Form Component class, you simply create a public function and add the <code>#[OnFormSaving]</code> attribute right above it. CRUDBooster will automatically find it and run it at the right time.</p><p>PHP</p><pre><code><code>use CrudBooster\Attributes\OnFormSaving;
// Make sure you are in your Form Component class, e.g., ProductsForm.php

class ProductsForm extends BaseFormComponent
{
    public function init() 
    {
        // Your form fields are defined here...
    }

    #[OnFormSaving]
    public function beforeSave($model, $data, $uuid = null)
    {
        // Your custom logic goes here!
        // This code will run right before the data is saved.
    }
}
</code></code></pre><p>CRUDBooster passes three arguments to your function:</p><ul><li><p><code>$model</code>: The model class for the module.</p></li><li><p><code>$data</code>: An array containing all the data submitted from the form.</p></li><li><p><code>$uuid</code>: The unique ID of the record (this will be <code>null</code> if you're creating a new record).</p></li></ul><h4>Use Case: Custom Validation</h4><p>Imagine you want to prevent a user from creating a product if another product with a similar name already exists. This is a perfect job for <code>#[OnFormSaving]</code>.</p><p>PHP</p><pre><code><code>use App\Cb\Modules\Products\Models\Products;
use CrudBooster\Attributes\OnFormSaving;
use Illuminate\Support\Str;

//... inside your form component

#[OnFormSaving]
public function beforeSave($model, $data, $uuid = null)
{
    // Let's check for a similar product name
    $similarProduct = Products::where('name', 'like', $data['name'].'%')-&gt;first();

    // If we're creating a new product and a similar one exists...
    if (!$uuid &amp;&amp; $similarProduct) {
        // Stop the process and throw an error!
        throw new \Exception("A product with a very similar name already exists. Please choose a different name.");
    }
}
</code></code></pre><p>With this simple function, the save operation will be halted if our condition is met, and the user will see an error message. Clean and effective!</p><div><hr></div><h3>Taking Action <em>After</em> a Successful Save with <code>#[OnFormSaved]</code></h3><p>Once your data is safely stored in the database, you might want to trigger a follow-up action. That's where <code>#[OnFormSaved]</code> comes in. It runs <em>after</em> the <code>INSERT</code> or <code>UPDATE</code> query has successfully completed.</p><h4>How to Use It</h4><p>Just like before, you define a public function in your Form Component and add the <code>#[OnFormSaved]</code> attribute.</p><p>PHP</p><pre><code><code>use CrudBooster\Attributes\OnFormSaved;
// Make sure you are in your Form Component class

class ProductsForm extends BaseFormComponent
{
    public function init() 
    {
        // Your form fields are defined here...
    }

    #[OnFormSaved]
    public function afterSave($model, $data, $uuid = null)
    {
        // Your custom logic goes here!
        // This code will run right after the data has been successfully saved.
    }
}
</code></code></pre><p>The arguments are the same, giving you full context about the data that was just saved.</p><h4>Use Case: Sending a Notification Email</h4><p>A classic example is sending a notification when a new record is created. Let's say we want to email an admin every time a new product is added to the catalog.</p><p>PHP</p><pre><code><code>use CrudBooster\Attributes\OnFormSaved;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;

//... inside your form component

#[OnFormSaved]
public function afterSave($model, $data, $uuid = null)
{
    // Check if it's a new record. The $uuid is only available after saving a new entry.
    // If $data['id'] is present, it's an update, so we can also check that.
    $isCreating = empty($data['id']);

    if ($isCreating) {
        $productName = $data['name'];
        $adminEmail = 'admin@yourapp.com';
        
        // Send an email
        // Mail::to($adminEmail)-&gt;send(new NewProductNotification($productName));

        // Or just log a message for demonstration
        Log::info("A new product '{$productName}' has been added with UUID: {$uuid}");
    }
}
</code></code></pre><p>Now, every time a new product is created, your application can automatically fire off an email or log the event. Other great use cases include clearing a specific cache, updating a related model, or pushing data to an external API.</p><h3>Wrap-Up</h3><p>These two simple attributes, <code>#[OnFormSaving]</code> and <code>#[OnFormSaved]</code>, give you incredible power to extend CRUDBooster's functionality. They allow you to add complex business logic directly into your modules in a way that is clean, maintainable, and upgrade-safe.</p><div><hr></div><p>Ready to build powerful admin panels faster than ever? <strong><a href="https://crudbooster.com/">Download CRUDBooster and get started today!</a></strong></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Building Master-Detail Relationships in CRUDBooster: A Complete Guide]]></title><description><![CDATA[Ever found yourself needing to manage related data in your admin panel?]]></description><link>https://crudbooster.substack.com/p/building-master-detail-relationships</link><guid isPermaLink="false">https://crudbooster.substack.com/p/building-master-detail-relationships</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Sat, 19 Jul 2025 10:09:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!_2En!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_2En!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_2En!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png 424w, https://substackcdn.com/image/fetch/$s_!_2En!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png 848w, https://substackcdn.com/image/fetch/$s_!_2En!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png 1272w, https://substackcdn.com/image/fetch/$s_!_2En!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_2En!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png" width="1456" height="809" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:809,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1284761,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/168702462?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_2En!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png 424w, https://substackcdn.com/image/fetch/$s_!_2En!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png 848w, https://substackcdn.com/image/fetch/$s_!_2En!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png 1272w, https://substackcdn.com/image/fetch/$s_!_2En!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09fdeb32-d143-4def-8a40-02e4d077e87f_1868x1038.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Ever found yourself needing to manage related data in your admin panel? Like categories and their subcategories, or customers and their orders? If you're using CRUDBooster, you're in luck! The Master-Detail (Sub Module) feature makes this incredibly straightforward.</p><p>Let me walk you through everything you need to know about implementing master-detail relationships in CRUDBooster, from the basics to real-world examples.</p><h2>What Are Master-Detail Relationships?</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZiiY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c290a03-8e2c-4e3d-baa6-b6ab489d0d71_1688x759.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZiiY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c290a03-8e2c-4e3d-baa6-b6ab489d0d71_1688x759.png 424w, https://substackcdn.com/image/fetch/$s_!ZiiY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c290a03-8e2c-4e3d-baa6-b6ab489d0d71_1688x759.png 848w, https://substackcdn.com/image/fetch/$s_!ZiiY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c290a03-8e2c-4e3d-baa6-b6ab489d0d71_1688x759.png 1272w, https://substackcdn.com/image/fetch/$s_!ZiiY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c290a03-8e2c-4e3d-baa6-b6ab489d0d71_1688x759.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZiiY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c290a03-8e2c-4e3d-baa6-b6ab489d0d71_1688x759.png" width="1456" height="655" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7c290a03-8e2c-4e3d-baa6-b6ab489d0d71_1688x759.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:655,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZiiY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c290a03-8e2c-4e3d-baa6-b6ab489d0d71_1688x759.png 424w, https://substackcdn.com/image/fetch/$s_!ZiiY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c290a03-8e2c-4e3d-baa6-b6ab489d0d71_1688x759.png 848w, https://substackcdn.com/image/fetch/$s_!ZiiY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c290a03-8e2c-4e3d-baa6-b6ab489d0d71_1688x759.png 1272w, https://substackcdn.com/image/fetch/$s_!ZiiY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c290a03-8e2c-4e3d-baa6-b6ab489d0d71_1688x759.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Think of master-detail relationships as parent-child data structures. The master (parent) contains the main record, while the detail (child) contains related records that belong to that master. Common examples include:</p><ul><li><p><strong>Categories &#8594; Subcategories</strong></p></li><li><p><strong>Customers &#8594; Orders</strong></p></li><li><p><strong>Projects &#8594; Tasks</strong></p></li><li><p><strong>Invoices &#8594; Invoice Items</strong></p></li></ul><p>In traditional admin panels, you'd typically navigate between separate pages to manage these relationships. With CRUDBooster's Sub Module feature, you can manage both the master and detail records from a single interface - pretty neat, right?</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><h2>Prerequisites</h2><p>Before diving in, make sure you have:</p><ol><li><p><strong>CRUDBooster 7.x</strong> installed and running</p></li><li><p><strong>Two related database tables</strong> with a foreign key relationship</p></li><li><p><strong>Basic understanding</strong> of CRUDBooster module creation</p></li><li><p><strong>Generated modules</strong> for both your master and detail tables</p></li></ol><p>For this tutorial, I'll use a practical example: managing categories and their subcategories.</p><h2>Setting Up the Database Structure</h2><p>Let's start with a simple database structure. You'll need two tables with a foreign key relationship:</p><pre><code><code>-- Categories table (Master)
CREATE TABLE categories (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- Subcategories table (Detail)
CREATE TABLE subcategories (
    id INT PRIMARY KEY AUTO_INCREMENT,
    category_id INT NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (category_id) REFERENCES categories(id)
);
</code></code></pre><p>The key here is the <code>category_id</code> foreign key in the subcategories table - this links each subcategory to its parent category.</p><h2>Step 1: Generate Your Modules</h2><p>First, you'll need to create modules for both tables. You can do this through the CRUDBooster admin panel or via command line:</p><pre><code><code># Generate category module
php artisan cb:crud categories --name=Categories

# Generate subcategory module
php artisan cb:crud subcategories --name=Subcategories
</code></code></pre><p>This creates all the necessary files for both modules. At this point, you have two separate modules that work independently.</p><h2>Step 2: Configure the Master Module</h2><p>Now comes the magic! Navigate to your master module's form component. In our case, that's the <code>CategoryForm</code> component located at <code>app/Cb/Modules/Categories/Livewire/CategoriesForm.php</code>.</p><p>Here's how to integrate the sub-module:</p><pre><code><code>&lt;?php

namespace App\Cb\Modules\Categories\Livewire;

use App\Cb\Modules\Categories\Services\CategoriesService;
use App\Cb\Modules\Categories\Models\Categories as CategoriesModel;
use App\Cb\Modules\Subcategories\Livewire\Subcategories;
use CrudBooster\Livewire\BaseFormComponent;
use CrudBooster\Livewire\FormBuilder\Form;
use CrudBooster\Components\MasterDetail\SubModule;

class CategoriesForm extends BaseFormComponent
{
    public $pageTitle = "Categories";
    protected $modelService = CategoriesService::class;
    protected $modelName = CategoriesModel::class;

    public function init()
    {
        // Configure your form fields as usual
        $this-&gt;makeForm([
            Form::add(label: "Name", key: "name", type: "text", validation: "required"),
            Form::add(label: "Description", key: "description", type: "textarea"),
        ]);

        // Here's where the magic happens!
        $this-&gt;addSubModule([
            SubModule::create(Subcategories::class)-&gt;foreignKey('category_id'),
        ]);
    }
}
</code></code></pre><p>Let me break down what's happening here:</p><ul><li><p><strong>SubModule::create()</strong>: This creates a new sub-module instance</p></li><li><p><strong>Subcategories::class</strong>: This refers to the browse component (not the form component!) of your detail module</p></li><li><p><strong>foreignKey('category_id')</strong>: This specifies which field links the detail records to the master record</p></li></ul><h2>Step 3: Handle Menu Visibility (Optional)</h2><p>Since your subcategories are now accessible through the categories module, you might want to hide the standalone subcategories menu. You can do this in the CRUDBooster admin panel under Menu Management, or simply leave it visible if you want both access methods.</p><h2>Real-World Use Cases</h2><p>Let me show you some practical examples of where master-detail relationships shine:</p><h3>E-commerce Product Management</h3><pre><code><code>// In ProductsForm.php
$this-&gt;addSubModule([
    SubModule::create(ProductVariants::class)-&gt;foreignKey('product_id'),
    SubModule::create(ProductImages::class)-&gt;foreignKey('product_id'),
]);
</code></code></pre><p>This allows you to manage product variants and images directly from the product editing page.</p><h3>Customer Relationship Management</h3><pre><code><code>// In CustomersForm.php
$this-&gt;addSubModule([
    SubModule::create(CustomerOrders::class)-&gt;foreignKey('customer_id'),
    SubModule::create(CustomerNotes::class)-&gt;foreignKey('customer_id'),
]);
</code></code></pre><p>Perfect for viewing all customer orders and notes in one place.</p><h3>Project Management</h3><pre><code><code>// In ProjectsForm.php
$this-&gt;addSubModule([
    SubModule::create(ProjectTasks::class)-&gt;foreignKey('project_id'),
    SubModule::create(ProjectFiles::class)-&gt;foreignKey('project_id'),
]);
</code></code></pre><p>Keep all project-related data organized and easily accessible.</p><h2>Advanced Configuration</h2><h3>Multiple Sub-Modules</h3><p>You can add multiple sub-modules to a single master record:</p><pre><code><code>$this-&gt;addSubModule([
    SubModule::create(Subcategories::class)-&gt;foreignKey('category_id'),
    SubModule::create(CategoryAttributes::class)-&gt;foreignKey('category_id'),
    SubModule::create(CategoryImages::class)-&gt;foreignKey('category_id'),
]);
</code></code></pre><h3>Custom Foreign Key Names</h3><p>If your foreign key doesn't follow the standard naming convention:</p><pre><code><code>$this-&gt;addSubModule([
    SubModule::create(Subcategories::class)-&gt;foreignKey('parent_category_id'),
]);
</code></code></pre><h2>What You Get Out of the Box</h2><p>When you implement master-detail relationships, CRUDBooster automatically provides:</p><ol><li><p><strong>Integrated Interface</strong>: Sub-modules appear as tabs or sections within the master record's detail page</p></li><li><p><strong>Automatic Filtering</strong>: Detail records are automatically filtered to show only those belonging to the current master record</p></li><li><p><strong>Context Awareness</strong>: New detail records automatically inherit the master record's ID</p></li><li><p><strong>Seamless Navigation</strong>: Users can manage related data without leaving the master record context</p></li></ol><h2>Best Practices</h2><p>Here are some tips to get the most out of master-detail relationships:</p><h3>1. Plan Your Data Structure</h3><p>Before implementing, think about which relationships truly benefit from this approach. Not every related table needs to be a sub-module.</p><h3>2. Consider User Experience</h3><p>Ask yourself: "Would users expect to manage this data together?" If yes, it's a good candidate for master-detail.</p><h3>3. Performance Considerations</h3><p>While convenient, loading multiple sub-modules can impact performance. Use this feature judiciously for high-traffic applications.</p><h3>4. Maintain Data Integrity</h3><p>Ensure your foreign key constraints are properly set up in the database to prevent orphaned records.</p><h2>Troubleshooting Common Issues</h2><h3>Sub-Module Not Appearing</h3><ul><li><p>Double-check that you're referencing the browse component class, not the form component</p></li><li><p>Verify the foreign key name matches your database column</p></li><li><p>Ensure the sub-module class exists and is properly imported</p></li></ul><h3>Foreign Key Errors</h3><ul><li><p>Confirm your database foreign key constraints are set up correctly</p></li><li><p>Check that the foreign key field name matches exactly</p></li></ul><h3>Permission Issues</h3><ul><li><p>Make sure users have appropriate permissions for both master and detail modules</p></li></ul><h2>The Result</h2><p>Once implemented, your master-detail interface will look clean and professional. Users can view the master record details at the top, with related detail records displayed in an organized section below. It's intuitive, efficient, and significantly improves the user experience.</p><p>The beauty of CRUDBooster's master-detail feature lies in its simplicity. With just a few lines of code, you transform separate, disconnected modules into a cohesive, user-friendly interface that makes data management a breeze.</p><h2>Ready to Build Better Admin Panels?</h2><p>Master-detail relationships are just one of the many powerful features that make CRUDBooster a game-changer for rapid application development. Whether you're building a simple admin panel or a complex business application, CRUDBooster provides the tools you need to create professional, feature-rich interfaces in record time.</p><p><strong>Ready to experience the power of CRUDBooster for yourself?</strong> <a href="https://crudbooster.com/">Download CRUDBooster today</a> and start building better admin panels in minutes, not hours. Your future self (and your users) will thank you!</p>]]></content:encoded></item><item><title><![CDATA[Mastering CRUDBooster Column Transforms: A Complete Guide to transform, transformWhen, and transformWithRow]]></title><description><![CDATA[When building admin panels with CRUDBooster, you'll often need to customize how data appears in your browse tables.]]></description><link>https://crudbooster.substack.com/p/mastering-crudbooster-column-transforms</link><guid isPermaLink="false">https://crudbooster.substack.com/p/mastering-crudbooster-column-transforms</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Wed, 16 Jul 2025 02:01:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!sGNI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sGNI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sGNI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png 424w, https://substackcdn.com/image/fetch/$s_!sGNI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png 848w, https://substackcdn.com/image/fetch/$s_!sGNI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png 1272w, https://substackcdn.com/image/fetch/$s_!sGNI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sGNI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png" width="1456" height="812" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/78427969-31ce-443f-bd3a-73253501f249_2062x1150.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:812,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1536336,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/168435780?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sGNI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png 424w, https://substackcdn.com/image/fetch/$s_!sGNI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png 848w, https://substackcdn.com/image/fetch/$s_!sGNI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png 1272w, https://substackcdn.com/image/fetch/$s_!sGNI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78427969-31ce-443f-bd3a-73253501f249_2062x1150.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When building admin panels with CRUDBooster, you'll often need to customize how data appears in your browse tables. Maybe you want to format names, add status badges, or display complex data relationships. That's where CRUDBooster's powerful column transform features come in handy.</p><p>In this tutorial, we'll explore three essential transform methods that will take your data presentation from basic to brilliant: <code>transform</code>, <code>transformWhen</code>, and <code>transformWithRow</code>.</p><h2>Prerequisites</h2><p>Before diving into column transforms, make sure you have:</p><ul><li><p><strong>CRUDBooster v7.0+</strong> installed and configured</p></li><li><p>Basic understanding of Laravel and PHP</p></li><li><p>A CRUDBooster module already set up</p></li><li><p>Familiarity with CRUDBooster's column system using <code>Column::add()</code></p></li></ul><p>If you're new to CRUDBooster columns, you should know how to create basic columns:</p><pre><code><code>use CrudBooster\Livewire\ColumnBuilder\Column;

Column::add(label: 'Name', key: 'users.name')
</code></code></pre><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><h2>Understanding Column Transforms</h2><p>Column transforms allow you to modify how data appears in your browse tables without changing the underlying database values. Think of them as presentation filters that run when displaying data to users.</p><h2>1. Basic Transform: The Foundation</h2><p>Imagine you're managing an e-commerce admin panel where product prices are stored as plain numbers in the database (like <code>29.99</code>), but you want to display them with proper currency formatting (<code>$29.99</code>) in your browse table. Or perhaps you have user names stored in lowercase, but you want to display them in title case for better readability.</p><p>This is where the <code>transform</code> method shines. It's your go-to solution for simple data modifications that only need the raw column value to work with. Think of it as a filter that takes the raw database value and returns a beautifully formatted version for display.</p><p><strong>Common use cases for </strong><code>transform</code><strong>:</strong></p><ul><li><p>Currency formatting (<code>1500</code> &#8594; <code>$1,500.00</code>)</p></li><li><p>Text case conversion (<code>john doe</code> &#8594; <code>John Doe</code>)</p></li><li><p>Adding HTML styling or icons</p></li><li><p>Date formatting (<code>2024-01-15</code> &#8594; <code>Jan 15, 2024</code>)</p></li><li><p>Truncating long text with ellipsis</p></li><li><p>Adding units to numbers (<code>25</code> &#8594; <code>25 kg</code>)</p></li></ul><p>The transform function receives one parameter: the raw column value, and expects you to return the formatted version.</p><h3>Basic Usage</h3><pre><code><code>use CrudBooster\Livewire\ColumnBuilder\Column;

class UsersBrowse extends BaseBrowseComponent
{
    public function init(): void
    {
        $this-&gt;makeColumns([
            Column::add(label: 'Name', key: 'users.name')
                -&gt;transform(function ($value) {
                    return strtoupper($value);
                }),
        ]);
    }
}
</code></code></pre><h3>Real-World Examples</h3><p><strong>Formatting Currency:</strong></p><pre><code><code>Column::add(label: 'Price', key: 'price')
    -&gt;transform(function ($value) {
        return '$' . number_format($value, 2);
    }),
</code></code></pre><p><strong>Adding HTML Styling:</strong></p><pre><code><code>Column::add(label: 'Status', key: 'status')
    -&gt;transform(function ($value) {
        return '&lt;span class="font-semibold text-blue-600"&gt;' . ucfirst($value) . '&lt;/span&gt;';
    }),
</code></code></pre><p><strong>Date Formatting:</strong></p><pre><code><code>Column::add(label: 'Created', key: 'created_at')
    -&gt;transform(function ($value) {
        return $value ? date('M j, Y', strtotime($value)) : '-';
    }),
</code></code></pre><h2>2. Conditional Transform: transformWhen</h2><p>Picture this scenario: you're building an order management system where most orders have a "standard" status that you want to display normally, but "urgent" orders need to stand out with red text and a warning icon. Or maybe you're managing a student grading system where you want to highlight A-grade students with gold stars, but leave other grades as they are.</p><p>This is exactly what <code>transformWhen</code> was designed for. Instead of transforming every single value in a column, it only applies your transformation when specific conditions are met. It's like having a smart filter that says "only change the appearance if this value matches my criteria."</p><p><strong>Perfect scenarios for </strong><code>transformWhen</code><strong>:</strong></p><ul><li><p>Highlighting critical status values (urgent orders, overdue tasks)</p></li><li><p>Adding visual indicators for special conditions (VIP customers, premium accounts)</p></li><li><p>Conditional formatting based on specific values</p></li><li><p>Adding warnings or alerts for certain states</p></li><li><p>Applying different styling rules for different categories</p></li></ul><p>The method works in two ways: you can check for exact value matches, or use a closure function for more complex conditions. When the condition is met, your transformation function runs. When it's not met, the original value displays unchanged.</p><h3>Basic Syntax</h3><pre><code><code>Column::add('Status', 'status')
    -&gt;transformWhen('active', function($value) {
        return '&lt;span class="text-green-600 font-bold"&gt;' . ucfirst($value) . '&lt;/span&gt;';
    });
</code></code></pre><h3>Practical Examples</h3><p><strong>Highlighting Important Status:</strong></p><pre><code><code>Column::add('Order Status', 'status')
    -&gt;transformWhen('urgent', function($value) {
        return '&#128680; ' . strtoupper($value);
    });
</code></code></pre><p><strong>Conditional Formatting:</strong></p><pre><code><code>Column::add('Score', 'score')
    -&gt;transformWhen(function($value) {
        return $value &gt;= 90;
    }, function($value) {
        return '&lt;span class="text-green-600 font-bold"&gt;&#11088; ' . $value . '&lt;/span&gt;';
    });
</code></code></pre><p><strong>Multiple Conditions:</strong></p><pre><code><code>// You can chain multiple transformWhen calls
Column::add('Priority', 'priority')
    -&gt;transformWhen('high', function($value) {
        return '&lt;span class="text-red-600"&gt;&#128308; High Priority&lt;/span&gt;';
    })
    -&gt;transformWhen('low', function($value) {
        return '&lt;span class="text-gray-400"&gt;&#9898; Low Priority&lt;/span&gt;';
    });
</code></code></pre><h2>3. Advanced Transform: transformWithRow</h2><p>Now let's tackle the most powerful scenario. Imagine you're building a user management interface where you want to display a user's full profile information in a single column - their name, email, profile picture, online status, and registration date. But here's the catch: these pieces of information are stored in different columns across your database.</p><p>Or consider an e-commerce order listing where you want to show a comprehensive order summary that includes the order number, customer name, total items, order value, and shipping status - all beautifully formatted in one column. You can't do this with simple <code>transform</code> because you need access to multiple fields from the same row.</p><p>This is where <code>transformWithRow</code> becomes your secret weapon. Unlike the previous methods that only give you access to a single column value, this method provides the entire row object, giving you access to all fields in that record. It's like having a complete toolkit where you can mix and match data from different columns to create rich, informative displays.</p><p><strong>Ideal use cases for </strong><code>transformWithRow</code><strong>:</strong></p><ul><li><p>Creating user profile cards with avatar, name, and status</p></li><li><p>Building comprehensive product listings with price, stock, and category</p></li><li><p>Generating order summaries with customer and item details</p></li><li><p>Making action buttons that need row IDs or other contextual data</p></li><li><p>Combining relationship data from joined tables</p></li><li><p>Creating complex formatted displays that need multiple data points</p></li></ul><p>The function receives the entire row object, so you can access any field using <code>$row-&gt;field_name</code> syntax. This gives you unlimited flexibility in creating sophisticated data presentations.</p><h3>Basic Usage</h3><pre><code><code>Column::add(label: 'User Info', key: 'name')
    -&gt;transformWithRow(function($row) {
        return strtoupper($row-&gt;name) . "&lt;br/&gt;&lt;small&gt;" . $row-&gt;email . "&lt;/small&gt;";
    });
</code></code></pre><h3>Complex Examples</h3><p><strong>Building User Cards:</strong></p><pre><code><code>Column::add('User Profile', 'name')
    -&gt;transformWithRow(function($row) {
        $avatar = $row-&gt;avatar ? "&lt;img src='{$row-&gt;avatar}' class='w-8 h-8 rounded-full inline-block mr-2'&gt;" : '&#128100;';
        $status = $row-&gt;is_active ? '&lt;span class="text-green-500"&gt;&#9679;&lt;/span&gt;' : '&lt;span class="text-gray-400"&gt;&#9679;&lt;/span&gt;';
        
        return $avatar . $row-&gt;name . ' ' . $status . "&lt;br/&gt;&lt;small class='text-gray-500'&gt;" . $row-&gt;email . "&lt;/small&gt;";
    });
</code></code></pre><p><strong>Creating Action Links:</strong></p><pre><code><code>Column::add('Quick Actions', 'id')
    -&gt;transformWithRow(function($row) {
        $editUrl = route('users.edit', $row-&gt;id);
        $viewUrl = route('users.show', $row-&gt;id);
        
        return "&lt;a href='{$editUrl}' class='btn btn-sm btn-primary mr-1'&gt;Edit&lt;/a&gt;" .
               "&lt;a href='{$viewUrl}' class='btn btn-sm btn-secondary'&gt;View&lt;/a&gt;";
    });
</code></code></pre><p><strong>Relationship Data Display:</strong></p><pre><code><code>Column::add('Order Summary', 'order_number')
    -&gt;transformWithRow(function($row) {
        $customerName = $row-&gt;customer_name ?? 'Unknown Customer';
        $totalItems = $row-&gt;items_count ?? 0;
        $orderValue = $row-&gt;total_amount ?? 0;
        
        return "&lt;strong&gt;#{$row-&gt;order_number}&lt;/strong&gt;&lt;br/&gt;" .
               "&lt;small&gt;Customer: {$customerName}&lt;/small&gt;&lt;br/&gt;" .
               "&lt;small&gt;{$totalItems} items &#8226; $" . number_format($orderValue, 2) . "&lt;/small&gt;";
    });
</code></code></pre><h2>Advanced Use Cases and Patterns</h2><h3>Combining Transforms with Badges</h3><p>In many admin panels, you'll encounter situations where you need to display status information in a visually appealing way. Think about order statuses, user account states, or project phases - these often benefit from color-coded badges that immediately communicate the current state to users.</p><p>CRUDBooster provides built-in badge methods that work seamlessly with the transform system. However, sometimes you need more control over the badge appearance or want to add custom icons and styling. Here's how you can leverage both approaches:</p><pre><code><code>// Using built-in badgeable methods
Column::add('Status', 'status')
    -&gt;badgeable([
        'active' =&gt; 'success',
        'inactive' =&gt; 'danger',
        'pending' =&gt; 'warning',
    ]);

// Custom badge with transform
Column::add('Custom Status', 'status')
    -&gt;transformWithRow(function($row) {
        $badges = [
            'completed' =&gt; '&lt;span class="badge badge-success"&gt;&#9989; Completed&lt;/span&gt;',
            'processing' =&gt; '&lt;span class="badge badge-warning"&gt;&#9203; Processing&lt;/span&gt;',
            'failed' =&gt; '&lt;span class="badge badge-danger"&gt;&#10060; Failed&lt;/span&gt;',
        ];
        
        return $badges[$row-&gt;status] ?? '&lt;span class="badge badge-secondary"&gt;Unknown&lt;/span&gt;';
    });
</code></code></pre><h3>Working with Relationships</h3><p>One of the most common challenges in admin panels is displaying related data efficiently. For example, in a product listing, you might want to show category information alongside each product, or in a user table, you might want to display department details.</p><p>Rather than loading relationships separately (which can cause N+1 query problems), the most efficient approach is to join the related tables and access the joined data directly in your transforms. This gives you all the relationship data you need while maintaining optimal database performance.</p><pre><code><code>Column::add('Category Info', 'category_name')
    -&gt;transformWithRow(function($row) {
        // Using joined category data
        if ($row-&gt;category_name) {
            return "&lt;strong&gt;{$row-&gt;category_name}&lt;/strong&gt;&lt;br/&gt;" .
                   "&lt;small class='text-gray-500'&gt;{$row-&gt;category_description}&lt;/small&gt;";
        }
        return '&lt;span class="text-gray-400"&gt;No Category&lt;/span&gt;';
    });
</code></code></pre><h3>Performance Considerations</h3><p>When working with large datasets or complex transforms, performance becomes crucial. The key principle to remember is that transform functions run for every single row in your table, so any inefficiency gets multiplied by the number of records you're displaying.</p><p>For relationship data, always use joins in your <code>hookQuery</code> method rather than lazy loading relationships within transforms. This ensures all the data you need is fetched in a single, efficient query:</p><pre><code><code>// In your browse component's hookQuery method
$this-&gt;hookQuery(function ($query) {
    $query-&gt;join('categories', 'products.category_id', '=', 'categories.id')
          -&gt;select('products.*', 'categories.name as category_name', 'categories.description as category_description');
});
</code></code></pre><h3>Error Handling in Transforms</h3><p>When working with real-world data, you'll inevitably encounter unexpected values - null data, malformed JSON, missing files, or corrupt information. Since transforms run on every row of your table, a single error can break your entire page display.</p><p>The golden rule is to always anticipate what could go wrong and provide graceful fallbacks. This is especially important when working with user-generated content, external API data, or any kind of processed information that might not be in the expected format.</p><pre><code><code>Column::add('Processed Data', 'raw_data')
    -&gt;transform(function ($value) {
        try {
            $data = json_decode($value, true);
            return $data['formatted_value'] ?? 'N/A';
        } catch (Exception $e) {
            return 'Invalid Data';
        }
    });
</code></code></pre><h2>Best Practices</h2><ol><li><p><strong>Keep transforms simple</strong>: Complex logic should be in your service layer, not in transforms</p></li><li><p><strong>Use appropriate escaping</strong>: When outputting HTML, ensure you're not creating XSS vulnerabilities</p></li><li><p><strong>Consider performance</strong>: Avoid heavy computations in transforms as they run for every row</p></li><li><p><strong>Be consistent</strong>: Use similar transform patterns across your application</p></li><li><p><strong>Test edge cases</strong>: Always test with null values, empty strings, and unexpected data</p></li></ol><h2>Combining with Other Column Features</h2><p>One of the most powerful aspects of CRUDBooster's column system is how seamlessly transforms integrate with other column features. You're not limited to just making data look pretty - you can also make it functional and interactive.</p><p>Consider a status column in an order management system. You want users to be able to filter by status (filterable), sort orders by their current state (sortable), search for specific statuses (searchable), AND display each status with appropriate visual styling (transform). With CRUDBooster, you can have all these features working together harmoniously:</p><pre><code><code>Column::add('Enhanced Status', 'status')
    -&gt;filterable()
    -&gt;sortable()
    -&gt;searchable()
    -&gt;transformWhen('active', function($value) {
        return '&#128994; ' . ucfirst($value);
    })
    -&gt;transformWhen('inactive', function($value) {
        return '&#128308; ' . ucfirst($value);
    });
</code></code></pre><p>This creates a column that's both highly functional for data management and visually appealing for users. The transforms don't interfere with the underlying data operations - filtering, sorting, and searching all work on the original database values, while the display layer shows your beautifully formatted versions.</p><h2>Troubleshooting Common Issues</h2><p><strong>Transform not showing:</strong></p><ul><li><p>Ensure you're returning a value from your transform function</p></li><li><p>Check that the column key matches your database field</p></li></ul><p><strong>HTML not rendering:</strong></p><ul><li><p>CRUDBooster allows HTML in transforms, but ensure your HTML is valid</p></li><li><p>Use proper escaping for user-generated content</p></li></ul><p><strong>Performance issues:</strong></p><ul><li><p>Move complex logic to your model or service layer</p></li><li><p>Use eager loading for relationship data</p></li></ul><h2>Conclusion</h2><p>CRUDBooster's transform features give you incredible flexibility in presenting your data. Whether you need simple formatting with <code>transform</code>, conditional styling with <code>transformWhen</code>, or complex data manipulation with <code>transformWithRow</code>, you now have the tools to create beautiful, functional admin interfaces.</p><p>Start with basic transforms and gradually incorporate more advanced patterns as your application grows. Remember, the goal is to make your data more readable and actionable for your users while maintaining clean, maintainable code.</p><p>Ready to transform your CRUDBooster experience? Start implementing these patterns in your next project and watch your admin panels come to life!</p><div><hr></div><h2>Get Started Today</h2><p>Ready to build powerful admin panels with CRUDBooster? Download the latest version and start transforming your data presentation today.</p><p><strong><a href="https://crudbooster.com/">Download CRUDBooster &#8594;</a></strong></p><p>Transform your Laravel development experience with CRUDBooster's powerful features and intuitive design. Join thousands of developers who are already building better admin panels faster.</p>]]></content:encoded></item><item><title><![CDATA[Understanding CRUDBooster's Relationship With HookQuery: A Complete Guide]]></title><description><![CDATA[When building complex admin panels and CRUD applications, one of the most common challenges developers face is managing relationships between different data tables.]]></description><link>https://crudbooster.substack.com/p/understanding-crudboosters-relationship</link><guid isPermaLink="false">https://crudbooster.substack.com/p/understanding-crudboosters-relationship</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Tue, 15 Jul 2025 10:36:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!5l5Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5l5Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5l5Q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png 424w, https://substackcdn.com/image/fetch/$s_!5l5Q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png 848w, https://substackcdn.com/image/fetch/$s_!5l5Q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png 1272w, https://substackcdn.com/image/fetch/$s_!5l5Q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5l5Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png" width="1456" height="812" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:812,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1613713,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/168374430?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5l5Q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png 424w, https://substackcdn.com/image/fetch/$s_!5l5Q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png 848w, https://substackcdn.com/image/fetch/$s_!5l5Q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png 1272w, https://substackcdn.com/image/fetch/$s_!5l5Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37efbf05-921b-458b-9cc3-c1ea8a8bf35e_2062x1150.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When building complex admin panels and CRUD applications, one of the most common challenges developers face is managing relationships between different data tables. CRUDBooster provides a powerful feature called <strong>HookQuery</strong> that allows you to create sophisticated join operations and custom queries for your browse pages. This comprehensive guide will walk you through everything you need to know about using relationships with HookQuery.</p><h2>What is HookQuery?</h2><p>HookQuery is CRUDBooster's modern approach to handling custom queries in your browse components. Unlike traditional hook functions, HookQuery provides a clean, intuitive way to intercept and modify the base query before it's executed. This allows you to add joins, filters, and complex relationships without compromising the framework's built-in functionality.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>Basic HookQuery Usage</h2><p>The simplest way to use HookQuery is by calling the <code>hookQuery()</code> method inside your <code>init()</code> method:</p><pre><code><code>use CrudBooster\Livewire\BaseBrowseComponent;
use CrudBooster\Livewire\ColumnBuilder\Column;
use Illuminate\Database\Query\Builder;

class User extends BaseBrowseComponent
{
    public function init(): void
    {
        // Hook Query for custom filtering
        $this-&gt;hookQuery(function (Builder $query) {
            $query-&gt;where('status', 'active');
        });

        $this-&gt;makeColumns([
            Column::add(label: 'Name', key: 'name'),
            Column::add(label: 'Email', key: 'email'),
            Column::add(label: 'Status', key: 'status'),
        ]);
    }
}
</code></code></pre><h2>Working with Simple Relationships</h2><p>Let's explore how to use HookQuery for basic table relationships. Consider a scenario where you have users and categories:</p><pre><code><code>class User extends BaseBrowseComponent
{
    public function init(): void
    {
        $this-&gt;hookQuery(function (Builder $query) {
            $query-&gt;join('categories', 'categories.id', '=', 'users.category_id');
        });

        $this-&gt;makeColumns([
            Column::add(label: 'Name', key: 'users.name'),
            Column::add(label: 'Email', key: 'users.email'),
            Column::add(label: 'Category', key: 'categories.name'),
        ]);
    }
}
</code></code></pre><p>Notice how we prefix the column keys with the table name (<code>users.name</code>, <code>categories.name</code>) to avoid conflicts.</p><h2>Advanced Multi-Table Relationships</h2><p>HookQuery really shines when dealing with complex multi-table relationships. Here's an example involving users, categories, and subcategories:</p><pre><code><code>class User extends BaseBrowseComponent
{
    public function init(): void
    {
        $this-&gt;hookQuery(function (Builder $query) {
            $query-&gt;join('categories', function (\Illuminate\Database\Query\JoinClause $joinClause) {
                $joinClause-&gt;on('categories.id', '=', 'users.category_id')
                           -&gt;where('categories.active', '=', 1);
            })
            -&gt;join('subcategories', function (\Illuminate\Database\Query\JoinClause $joinClause) {
                $joinClause-&gt;on('subcategories.id', '=', 'users.subcategory_id')
                           -&gt;where('subcategories.status', '=', 'published');
            });
        });

        $this-&gt;makeColumns([
            Column::add(label: 'Name', key: 'users.name'),
            Column::add(label: 'Email', key: 'users.email'),
            Column::add(label: 'Category', key: 'categories.name'),
            Column::add(label: 'Subcategory', key: 'subcategories.name'),
        ]);
    }
}
</code></code></pre><h2>Common Use Cases</h2><h3>1. E-commerce Product Listing</h3><pre><code><code>class Product extends BaseBrowseComponent
{
    public function init(): void
    {
        $this-&gt;hookQuery(function (Builder $query) {
            $query-&gt;join('categories', 'categories.id', '=', 'products.category_id')
                  -&gt;join('brands', 'brands.id', '=', 'products.brand_id')
                  -&gt;leftJoin('product_images', function($join) {
                      $join-&gt;on('product_images.product_id', '=', 'products.id')
                           -&gt;whereRaw('product_images.id = (SELECT MIN(id) FROM product_images WHERE product_id = products.id)');
                  })
                  -&gt;where('products.status', 'active')
                  -&gt;where('categories.is_visible', true);
        });

        $this-&gt;makeColumns([
            Column::add(label: 'Product Name', key: 'products.name'),
            Column::add(label: 'Category', key: 'categories.name'),
            Column::add(label: 'Brand', key: 'brands.name'),
            Column::add(label: 'Price', key: 'products.price'),
            Column::add(label: 'Stock', key: 'products.stock'),
            Column::add(label: 'Image', key: 'product_images.image_url')-&gt;image(),
        ]);
    }
}
</code></code></pre><h3>2. Order Management with Customer Details</h3><pre><code><code>class Order extends BaseBrowseComponent
{
    public function init(): void
    {
        $this-&gt;hookQuery(function (Builder $query) {
            $query-&gt;join('customers', 'customers.id', '=', 'orders.customer_id')
                  -&gt;join('order_statuses', 'order_statuses.id', '=', 'orders.status_id')
                  -&gt;leftJoin('shipping_addresses', 'shipping_addresses.order_id', '=', 'orders.id')
                  -&gt;selectRaw('orders.*, customers.name as customer_name, customers.email as customer_email, 
                             order_statuses.name as status_name, shipping_addresses.city as shipping_city');
        });

        $this-&gt;makeColumns([
            Column::add(label: 'Order ID', key: 'orders.id'),
            Column::add(label: 'Customer', key: 'customer_name'),
            Column::add(label: 'Email', key: 'customer_email'),
            Column::add(label: 'Status', key: 'status_name')-&gt;badgeable([
                'pending' =&gt; 'warning',
                'processing' =&gt; 'info',
                'completed' =&gt; 'success',
                'cancelled' =&gt; 'danger'
            ]),
            Column::add(label: 'Shipping City', key: 'shipping_city'),
            Column::add(label: 'Total', key: 'orders.total_amount'),
        ]);
    }
}
</code></code></pre><h3>3. User Management with Role Information</h3><pre><code><code>class User extends BaseBrowseComponent
{
    public function init(): void
    {
        $this-&gt;hookQuery(function (Builder $query) {
            $query-&gt;join('user_roles', 'user_roles.user_id', '=', 'users.id')
                  -&gt;join('roles', 'roles.id', '=', 'user_roles.role_id')
                  -&gt;leftJoin('departments', 'departments.id', '=', 'users.department_id')
                  -&gt;selectRaw('users.*, roles.name as role_name, departments.name as department_name')
                  -&gt;groupBy('users.id');
        });

        $this-&gt;makeColumns([
            Column::add(label: 'Name', key: 'users.name'),
            Column::add(label: 'Email', key: 'users.email'),
            Column::add(label: 'Role', key: 'role_name'),
            Column::add(label: 'Department', key: 'department_name'),
            Column::add(label: 'Status', key: 'users.status'),
        ]);
    }
}
</code></code></pre><h2>Advanced Filtering with HookQuery</h2><p>You can combine HookQuery with advanced filtering for more sophisticated data retrieval:</p><pre><code><code>class User extends BaseBrowseComponent
{
    public function init(): void
    {
        $this-&gt;hookQuery(function (Builder $query) {
            $query-&gt;join('categories', 'categories.id', '=', 'users.category_id')
                  -&gt;join('user_profiles', 'user_profiles.user_id', '=', 'users.id')
                  -&gt;where('users.created_at', '&gt;=', now()-&gt;subMonths(6))
                  -&gt;where('categories.type', 'premium')
                  -&gt;whereNotNull('user_profiles.phone');
        });

        $this-&gt;makeColumns([
            Column::add(label: 'Name', key: 'users.name'),
            Column::add(label: 'Email', key: 'users.email'),
            Column::add(label: 'Category', key: 'categories.name'),
            Column::add(label: 'Phone', key: 'user_profiles.phone'),
            Column::add(label: 'Created', key: 'users.created_at'),
        ]);
    }
}
</code></code></pre><h2>Performance Optimization Tips</h2><p>When using HookQuery with relationships, consider these performance optimization strategies:</p><h3>1. Use Proper Indexing</h3><p>Ensure your database tables have appropriate indexes on columns used in joins:</p><pre><code><code>CREATE INDEX idx_users_category_id ON users(category_id);
CREATE INDEX idx_categories_active ON categories(active);
</code></code></pre><h3>2. Select Only Required Columns</h3><p>Instead of selecting all columns, specify only what you need:</p><pre><code><code>$this-&gt;hookQuery(function (Builder $query) {
    $query-&gt;select([
        'users.id',
        'users.name',
        'users.email',
        'categories.name as category_name'
    ])
    -&gt;join('categories', 'categories.id', '=', 'users.category_id');
});
</code></code></pre><h3>3. Use Eager Loading for Related Data</h3><p>For complex relationships, consider using Laravel's eager loading:</p><pre><code><code>$this-&gt;hookQuery(function (Builder $query) {
    $query-&gt;with(['category', 'profile', 'roles']);
});
</code></code></pre><h2>Combining HookQuery with Other CRUDBooster Features</h2><p>HookQuery works seamlessly with other CRUDBooster features:</p><h3>With Advanced Filtering</h3><pre><code><code>public function init(): void
{
    $this-&gt;hookQuery(function (Builder $query) {
        $query-&gt;join('categories', 'categories.id', '=', 'users.category_id');
    });

    $this-&gt;makeColumns([
        Column::add(label: 'Name', key: 'users.name')-&gt;filterable(),
        Column::add(label: 'Category', key: 'categories.name')-&gt;filterSelectQuery(function() {
            return Category::query()
                -&gt;select('id as value', 'name as label')
                -&gt;where('active', true)
                -&gt;orderBy('name');
        }),
    ]);
}
</code></code></pre><h3>With Column Transformations</h3><pre><code><code>public function init(): void
{
    $this-&gt;hookQuery(function (Builder $query) {
        $query-&gt;join('categories', 'categories.id', '=', 'users.category_id');
    });

    $this-&gt;makeColumns([
        Column::add(label: 'User Info', key: 'users.name')-&gt;transformWithRow(function($row) {
            return "&lt;strong&gt;{$row-&gt;name}&lt;/strong&gt;&lt;br/&gt;&lt;small&gt;{$row-&gt;category_name}&lt;/small&gt;";
        }),
    ]);
}
</code></code></pre><h2>Troubleshooting Common Issues</h2><h3>1. Column Ambiguity</h3><p><strong>Problem</strong>: Error about ambiguous column names <strong>Solution</strong>: Always prefix column names with table names</p><pre><code><code>// Wrong
Column::add(label: 'Name', key: 'name')

// Correct
Column::add(label: 'Name', key: 'users.name')
</code></code></pre><h3>2. Missing Data</h3><p><strong>Problem</strong>: Some rows not appearing <strong>Solution</strong>: Check your join types (INNER vs LEFT JOIN)</p><pre><code><code>// Use LEFT JOIN for optional relationships
$query-&gt;leftJoin('categories', 'categories.id', '=', 'users.category_id');
</code></code></pre><h3>3. Performance Issues</h3><p><strong>Problem</strong>: Slow query execution <strong>Solution</strong>: Add proper indexes and optimize your joins</p><pre><code><code>// Add indexes in your migration
Schema::table('users', function (Blueprint $table) {
    $table-&gt;index('category_id');
    $table-&gt;index(['status', 'created_at']);
});
</code></code></pre><h2>Best Practices</h2><ol><li><p><strong>Always use table prefixes</strong> in column keys when working with joins</p></li><li><p><strong>Keep your HookQuery logic simple</strong> and focused on data retrieval</p></li><li><p><strong>Use appropriate join types</strong> (INNER, LEFT, RIGHT) based on your requirements</p></li><li><p><strong>Consider performance implications</strong> of complex joins</p></li><li><p><strong>Test your queries</strong> with large datasets to ensure scalability</p></li><li><p><strong>Use Laravel's Query Builder methods</strong> for consistency and security</p></li></ol><h2>Conclusion</h2><p>HookQuery is a powerful feature that makes CRUDBooster incredibly flexible for handling complex database relationships. By mastering this feature, you can create sophisticated admin panels that display related data from multiple tables with ease. The key is to understand your data structure, use appropriate join types, and always consider performance implications.</p><p>Whether you're building a simple blog admin or a complex e-commerce management system, HookQuery provides the tools you need to create efficient, maintainable, and powerful browse pages that can handle any relationship complexity your application requires.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p><strong>Ready to build powerful admin panels with complex relationships?</strong> <a href="https://crudbooster.com/">Download CRUDBooster now</a> and start creating sophisticated CRUD applications with ease. Get access to HookQuery and dozens of other powerful features that will accelerate your development process.</p>]]></content:encoded></item><item><title><![CDATA[Mastering Advanced Filtering in CRUDBooster: A Complete Guide to Streamline Your Data Management]]></title><description><![CDATA[Data filtering is the backbone of any robust admin panel.]]></description><link>https://crudbooster.substack.com/p/mastering-advanced-filtering-in-crudbooster</link><guid isPermaLink="false">https://crudbooster.substack.com/p/mastering-advanced-filtering-in-crudbooster</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Fri, 11 Jul 2025 02:04:22 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!OaXY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OaXY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OaXY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png 424w, https://substackcdn.com/image/fetch/$s_!OaXY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png 848w, https://substackcdn.com/image/fetch/$s_!OaXY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!OaXY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OaXY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png" width="1456" height="827" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:827,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1667414,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/167877966?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OaXY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png 424w, https://substackcdn.com/image/fetch/$s_!OaXY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png 848w, https://substackcdn.com/image/fetch/$s_!OaXY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!OaXY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82290ef3-9004-4fc7-bff6-684cf8550040_2056x1168.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Data filtering is the backbone of any robust admin panel. When you're dealing with thousands of records, the ability to quickly find exactly what you need isn't just convenient&#8212;it's essential. CRUDBooster's advanced filtering system transforms this challenge into an elegant solution, offering developers a powerful toolkit to create intuitive, user-friendly data interfaces.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>In this comprehensive guide, we'll explore CRUDBooster's filterable features, from basic implementation to advanced use cases that will revolutionize how your users interact with data.</p><h2>Understanding CRUDBooster's Filtering Philosophy</h2><p>Before diving into the technical details, it's important to understand what makes CRUDBooster's filtering system special. Unlike basic search functionality that works across all columns, CRUDBooster's filterable feature provides column-specific filtering with intelligent input types that match your data structure.</p><p>This means users can filter dates with date pickers, numbers with comparison operators, and text with smart search patterns&#8212;all automatically generated based on your column configuration.</p><h2>Getting Started: Basic Filterable Implementation</h2><p>The foundation of CRUDBooster's filtering system lies in the simple <code>filterable()</code> method. Here's how to enable basic filtering:</p><pre><code><code>use CrudBooster\Livewire\ColumnBuilder\Column;

class ProductsBrowse extends BaseBrowseComponent
{
    public function init(): void
    {
        $this-&gt;makeColumns([
            Column::add('Product Name', 'name')-&gt;filterable(),
            Column::add('Price', 'price')-&gt;filterable(),
            Column::add('Category', 'category_name')-&gt;filterable(),
        ]);
    }
}
</code></code></pre><p>With just the <code>filterable()</code> method, CRUDBooster automatically provides text-based filtering for each column. But this is just the beginning&#8212;the real power lies in specialized filter types.</p><h2>Advanced Filter Types: Matching Data to Interface</h2><h3>Text-Based Filtering with Contains</h3><p>The default filter behavior uses "contains" logic, perfect for searching product names, descriptions, or any text-based content:</p><pre><code><code>Column::add('Product Name', 'name')-&gt;filterContains()
// Users can search for partial matches like "Phone" to find "iPhone", "Samsung Phone", etc.
</code></code></pre><h3>Numeric Filtering with Comparison Operators</h3><p>For numerical data, CRUDBooster offers sophisticated comparison filters:</p><pre><code><code>// Find products above a certain price
Column::add('Price', 'price')-&gt;filterGreaterThan()

// Find products below a price threshold
Column::add('Price', 'price')-&gt;filterLessThan()

// Find products within a specific price range
Column::add('Stock Quantity', 'stock')-&gt;filterGreaterEqual()
Column::add('Minimum Order', 'min_order')-&gt;filterLessEqual()
</code></code></pre><p><strong>Real-world Example</strong>: An e-commerce admin panel where managers need to find:</p><ul><li><p>Premium products (price &gt; $100)</p></li><li><p>Low stock items (stock &lt; 10)</p></li><li><p>Bulk order products (minimum order &gt;= 50)</p></li></ul><h3>Date Range Filtering for Time-Based Data</h3><p>Date filtering is crucial for any business application. CRUDBooster's date range filter provides an intuitive interface:</p><pre><code><code>Column::add('Order Date', 'created_at')-&gt;filterDateRange()
</code></code></pre><p>This creates two date inputs (start and end date), allowing users to filter records within specific time periods&#8212;perfect for sales reports, order tracking, or any time-sensitive data analysis.</p><h3>Enum-Based Filtering for Status Fields</h3><p>When you have predefined status values, enum filtering provides a clean dropdown interface:</p><pre><code><code>Column::add('Order Status', 'status')-&gt;filterSelectEnum([
    'pending' =&gt; 'Pending',
    'processing' =&gt; 'Processing',
    'shipped' =&gt; 'Shipped',
    'delivered' =&gt; 'Delivered',
    'cancelled' =&gt; 'Cancelled'
])
</code></code></pre><p>This approach is ideal for:</p><ul><li><p>Order management systems</p></li><li><p>User status tracking</p></li><li><p>Project management tools</p></li><li><p>Content moderation panels</p></li></ul><h2>Database-Driven Filtering with Select Query</h2><p>One of CRUDBooster's most powerful features is the ability to create dynamic filters from database relationships:</p><pre><code><code>Column::add('Category', 'category_id')-&gt;filterSelectQuery(function() {
    return Category::query()
        -&gt;select('id as value', 'name as label')
        -&gt;where('is_active', true)
        -&gt;orderBy('name');
})
</code></code></pre><h3>Advanced Query Filtering with Custom Logic</h3><p>CRUDBooster v7.9.7 introduced custom search logic for query filters, enabling complex filtering scenarios:</p><pre><code><code>Column::add('Product Category', 'category_id')-&gt;filterSelectQuery(
    // Define dropdown options
    function() {
        return Category::query()
            -&gt;select('id as value', 'name as label')
            -&gt;where('is_active', true)
            -&gt;orderBy('name');
    },
    // Custom search logic when filter is applied
    function($query, $filterValue, $field) {
        $query-&gt;whereHas('category', function($categoryQuery) use ($filterValue) {
            $categoryQuery-&gt;where('name', 'like', '%' . $filterValue . '%')
                        -&gt;orWhere('description', 'like', '%' . $filterValue . '%');
        });
    }
)
</code></code></pre><p>This powerful combination allows you to:</p><ul><li><p>Create dropdown options from one query</p></li><li><p>Apply completely different filtering logic</p></li><li><p>Implement complex relationships and subqueries</p></li><li><p>Handle edge cases with custom business logic</p></li></ul><h2>Real-World Use Cases: Putting It All Together</h2><h3>E-Commerce Admin Panel</h3><p>Let's build a comprehensive product management interface:</p><pre><code><code>class ProductsBrowse extends BaseBrowseComponent
{
    public function init(): void
    {
        $this-&gt;makeColumns([
            // Basic text search for product discovery
            Column::add('Product Name', 'name')
                -&gt;filterContains(),
            
            // Price range filtering for inventory management
            Column::add('Price', 'price')
                -&gt;filterGreaterThan(),
            
            // Stock level monitoring
            Column::add('Stock', 'stock_quantity')
                -&gt;filterLessEqual(),
            
            // Date-based inventory tracking
            Column::add('Last Restocked', 'last_restocked_at')
                -&gt;filterDateRange(),
            
            // Status-based product management
            Column::add('Status', 'status')
                -&gt;filterSelectEnum([
                    'active' =&gt; 'Active',
                    'inactive' =&gt; 'Inactive',
                    'discontinued' =&gt; 'Discontinued'
                ]),
            
            // Category-based organization
            Column::add('Category', 'category_id')
                -&gt;filterSelectQuery(function() {
                    return Category::query()
                        -&gt;select('id as value', 'name as label')
                        -&gt;where('is_active', true)
                        -&gt;orderBy('name');
                }),
        ]);
    }
}
</code></code></pre><h3>Customer Support Dashboard</h3><p>For a customer support system, different filtering needs emerge:</p><pre><code><code>class TicketsBrowse extends BaseBrowseComponent
{
    public function init(): void
    {
        $this-&gt;makeColumns([
            // Quick ticket identification
            Column::add('Ticket ID', 'ticket_number')
                -&gt;filterContains(),
            
            // Priority-based filtering
            Column::add('Priority', 'priority')
                -&gt;filterSelectEnum([
                    'low' =&gt; 'Low',
                    'medium' =&gt; 'Medium',
                    'high' =&gt; 'High',
                    'urgent' =&gt; 'Urgent'
                ]),
            
            // Time-sensitive ticket management
            Column::add('Created Date', 'created_at')
                -&gt;filterDateRange(),
            
            // Agent assignment filtering
            Column::add('Assigned Agent', 'agent_id')
                -&gt;filterSelectQuery(function() {
                    return User::query()
                        -&gt;select('id as value', 'name as label')
                        -&gt;where('role', 'support_agent')
                        -&gt;where('is_active', true)
                        -&gt;orderBy('name');
                }),
            
            // Customer-specific filtering with advanced search
            Column::add('Customer', 'customer_id')
                -&gt;filterSelectQuery(
                    function() {
                        return Customer::query()
                            -&gt;select('id as value', 'name as label')
                            -&gt;orderBy('name');
                    },
                    function($query, $filterValue, $field) {
                        $query-&gt;whereHas('customer', function($customerQuery) use ($filterValue) {
                            $customerQuery-&gt;where('name', 'like', '%' . $filterValue . '%')
                                        -&gt;orWhere('email', 'like', '%' . $filterValue . '%')
                                        -&gt;orWhere('phone', 'like', '%' . $filterValue . '%');
                        });
                    }
                ),
        ]);
    }
}
</code></code></pre><h2>Best Practices for Optimal Filtering Experience</h2><h3>1. Choose the Right Filter Type for Your Data</h3><p>Match filter types to data characteristics:</p><ul><li><p><strong>Text data</strong>: Use <code>filterContains()</code> for flexible searching</p></li><li><p><strong>Numerical data</strong>: Use comparison filters (<code>filterGreaterThan()</code>, <code>filterLessEqual()</code>)</p></li><li><p><strong>Status fields</strong>: Use <code>filterSelectEnum()</code> for predefined options</p></li><li><p><strong>Relationships</strong>: Use <code>filterSelectQuery()</code> for dynamic options</p></li><li><p><strong>Time-based data</strong>: Use <code>filterDateRange()</code> for period selection</p></li></ul><h3>2. Optimize Database Queries</h3><p>When using <code>filterSelectQuery()</code>, ensure your queries are optimized:</p><pre><code><code>// Good: Specific fields, proper indexing
Column::add('Category', 'category_id')-&gt;filterSelectQuery(function() {
    return Category::query()
        -&gt;select('id as value', 'name as label')
        -&gt;where('is_active', true)
        -&gt;orderBy('name')
        -&gt;limit(100); // Prevent excessive options
})

// Better: With proper indexing on is_active and name columns
</code></code></pre><h3>3. Implement Progressive Disclosure</h3><p>For complex interfaces, consider which filters are most important and enable them selectively:</p><pre><code><code>class OrdersBrowse extends BaseBrowseComponent
{
    public function init(): void
    {
        $this-&gt;makeColumns([
            // Core filters - always enabled
            Column::add('Order Number', 'order_number')-&gt;filterable(),
            Column::add('Status', 'status')-&gt;filterSelectEnum([...]),
            Column::add('Order Date', 'created_at')-&gt;filterDateRange(),
            
            // Advanced filters - enabled based on user role or preference
            Column::add('Customer', 'customer_id')
                -&gt;filterSelectQuery(...)
                -&gt;filterable(auth()-&gt;user()-&gt;hasRole('manager')),
        ]);
    }
}
</code></code></pre><h3>4. Handle Large Datasets Intelligently</h3><p>For tables with millions of records, consider:</p><pre><code><code>// Limit dropdown options to prevent performance issues
Column::add('Product', 'product_id')-&gt;filterSelectQuery(function() {
    return Product::query()
        -&gt;select('id as value', 'name as label')
        -&gt;where('is_active', true)
        -&gt;orderBy('name')
        -&gt;limit(500); // Reasonable limit for dropdown
})
</code></code></pre><h2>Advanced Techniques: Custom Search Logic Patterns</h2><h3>Multi-Field Search Pattern</h3><p>Search across related fields for better user experience:</p><pre><code><code>Column::add('Customer', 'customer_id')-&gt;filterSelectQuery(
    function() {
        return Customer::query()
            -&gt;select('id as value', 'name as label')
            -&gt;orderBy('name');
    },
    function($query, $filterValue, $field) {
        $query-&gt;whereExists(function($subQuery) use ($filterValue) {
            $subQuery-&gt;select(DB::raw(1))
                    -&gt;from('customers')
                    -&gt;whereColumn('customers.id', '=', 'orders.customer_id')
                    -&gt;where(function($customerQuery) use ($filterValue) {
                        $customerQuery-&gt;where('name', 'like', '%' . $filterValue . '%')
                                    -&gt;orWhere('email', 'like', '%' . $filterValue . '%')
                                    -&gt;orWhere('phone', 'like', '%' . $filterValue . '%')
                                    -&gt;orWhere('company', 'like', '%' . $filterValue . '%');
                    });
        });
    }
)
</code></code></pre><h3>Time-Based Intelligence</h3><p>Implement smart date filtering with business logic:</p><pre><code><code>Column::add('Orders', 'order_id')-&gt;filterSelectQuery(
    function() {
        return Order::query()
            -&gt;select('id as value', 'order_number as label')
            -&gt;where('status', 'completed')
            -&gt;orderBy('created_at', 'desc')
            -&gt;limit(200);
    },
    function($query, $filterValue, $field) {
        // Only show recent high-value orders
        $query-&gt;whereBetween('created_at', [
            now()-&gt;subDays(30),
            now()
        ])-&gt;where('total_amount', '&gt;', 1000);
    }
)
</code></code></pre><h2>Troubleshooting Common Filtering Issues</h2><h3>Performance Optimization</h3><p>If your filters are slow, consider these optimizations:</p><ol><li><p><strong>Add database indexes</strong> on filtered columns</p></li><li><p><strong>Limit dropdown options</strong> to reasonable numbers</p></li><li><p><strong>Use eager loading</strong> for related data</p></li><li><p><strong>Implement caching</strong> for static filter options</p></li></ol><h3>User Experience Improvements</h3><ol><li><p><strong>Provide clear labels</strong> that match user mental models</p></li><li><p><strong>Group related filters</strong> logically</p></li><li><p><strong>Show filter states</strong> clearly to users</p></li><li><p><strong>Allow easy filter clearing</strong> for quick resets</p></li></ol><h2>Conclusion: Building Intuitive Data Interfaces</h2><p>CRUDBooster's advanced filtering system transforms raw data into actionable insights. By matching filter types to data characteristics, implementing smart search logic, and following user experience best practices, you can create admin panels that don't just display data&#8212;they empower users to find exactly what they need, when they need it.</p><p>The key to successful filtering implementation lies in understanding your users' workflows and providing the right tools for their specific tasks. Whether you're building an e-commerce dashboard, customer support system, or any data-driven application, CRUDBooster's filtering features provide the foundation for exceptional user experiences.</p><p>Start with basic filtering, then gradually add advanced features as your application grows. Your users will appreciate the thoughtful design, and you'll appreciate the robust, maintainable code that CRUDBooster enables.</p><p>Remember: great filtering isn't about having every possible option&#8212;it's about having the right options, implemented elegantly, and designed with your users' success in mind.</p><h2>Ready to Transform Your Data Management?</h2><p>Don't let your users struggle with overwhelming data tables. CRUDBooster's advanced filtering system is just one of the many powerful features that can revolutionize your admin panel development.</p><p><strong><a href="https://crudbooster.com">Download CRUDBooster today</a></strong> and start building intelligent, user-friendly data interfaces that your team will actually enjoy using. Join thousands of developers who have already discovered the power of rapid, professional admin panel development.</p><p>&#128640; <strong>Get started in minutes, not months.</strong></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Mastering Custom Search Logic in CRUDBooster: A Complete Guide to hookSearch]]></title><description><![CDATA[When building admin panels and data management systems, one of the most critical features users interact with is search functionality.]]></description><link>https://crudbooster.substack.com/p/mastering-custom-search-logic-in</link><guid isPermaLink="false">https://crudbooster.substack.com/p/mastering-custom-search-logic-in</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Thu, 10 Jul 2025 03:54:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!dzPm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dzPm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dzPm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png 424w, https://substackcdn.com/image/fetch/$s_!dzPm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png 848w, https://substackcdn.com/image/fetch/$s_!dzPm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!dzPm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dzPm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png" width="1456" height="827" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:827,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1624679,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/167877664?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dzPm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png 424w, https://substackcdn.com/image/fetch/$s_!dzPm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png 848w, https://substackcdn.com/image/fetch/$s_!dzPm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!dzPm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe525caca-bac8-4fe4-a3d1-af48b2768581_2056x1168.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When building admin panels and data management systems, one of the most critical features users interact with is search functionality. While CRUDBooster provides excellent out-of-the-box search capabilities, there are times when you need more sophisticated search logic that goes beyond simple column matching. This is where the <strong>hookSearch</strong> feature comes into play.</p><p>Introduced in CRUDBooster v7.8.0+, <code>hookSearch</code> allows developers to implement custom search logic in Livewire modules, giving you complete control over how search queries are processed and executed. Whether you need to search across relationships, implement fuzzy matching, or create complex conditional searches, hookSearch provides the flexibility you need.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>Understanding hookSearch</h2><p>The <code>hookSearch</code> feature is a powerful method that allows you to override the default search behavior in your CRUDBooster browse components. Instead of relying on the standard "LIKE" queries across defined columns, you can implement your own search logic that can be as simple or as complex as your application requires.</p><h3>Basic Syntax</h3><p>The basic syntax for implementing hookSearch is straightforward:</p><pre><code><code>$this-&gt;hookSearch(function($query, $search) {
    // Your custom search logic here
});
</code></code></pre><p>The closure function receives two parameters:</p><ul><li><p><code>$query</code>: The current query builder instance</p></li><li><p><code>$search</code>: The search term entered by the user</p></li></ul><h2>Getting Started: Basic Implementation</h2><p>Let's start with a simple example. Suppose you have a User module and want to search across name, email, and phone fields:</p><pre><code><code>&lt;?php

namespace App\Cb\Modules\Users\Livewire;

use CrudBooster\Livewire\BaseBrowseComponent;
use CrudBooster\Livewire\ColumnBuilder\Column;
use App\Models\User;

class Users extends BaseBrowseComponent
{
    public $modelName = User::class;
    
    public function init(): void
    {
        $this-&gt;makeColumns([
            Column::add(label: 'Name', key: 'name'),
            Column::add(label: 'Email', key: 'email'),
            Column::add(label: 'Phone', key: 'phone'),
        ]);
        
        $this-&gt;hookSearch(function($query, $search) {
            $query-&gt;where(function($q) use ($search) {
                $q-&gt;where('name', 'like', '%' . $search . '%')
                  -&gt;orWhere('email', 'like', '%' . $search . '%')
                  -&gt;orWhere('phone', 'like', '%' . $search . '%');
            });
        });
    }
}
</code></code></pre><p>In this example, when a user enters a search term, the system will look for matches in the name, email, or phone fields. The use of <code>where(function($q) use ($search)</code> ensures that the OR conditions are properly grouped.</p><h2>Advanced Use Cases</h2><h3>1. Searching Across Relationships</h3><p>One of the most powerful applications of hookSearch is searching across related tables. Let's say you have a Products module and want to search not only product names but also category names:</p><pre><code><code>$this-&gt;hookSearch(function($query, $search) {
    $query-&gt;where(function($q) use ($search) {
        $q-&gt;where('products.name', 'like', '%' . $search . '%')
          -&gt;orWhere('products.description', 'like', '%' . $search . '%')
          -&gt;orWhereHas('category', function($categoryQuery) use ($search) {
              $categoryQuery-&gt;where('name', 'like', '%' . $search . '%');
          });
    });
});
</code></code></pre><p>This implementation allows users to find products by searching for category names, making the search functionality much more intuitive and powerful.</p><h3>2. Smart Status-Based Search</h3><p>You can implement intelligent search logic that recognizes keywords and maps them to specific database values:</p><pre><code><code>$this-&gt;hookSearch(function($query, $search) {
    $searchLower = strtolower($search);
    
    // Search by status keywords
    if (str_contains($searchLower, 'active')) {
        $query-&gt;where('status', 'active');
        return;
    }
    
    if (str_contains($searchLower, 'inactive') || str_contains($searchLower, 'disabled')) {
        $query-&gt;where('status', 'inactive');
        return;
    }
    
    if (str_contains($searchLower, 'pending')) {
        $query-&gt;where('status', 'pending');
        return;
    }
    
    // Default search across multiple fields
    $query-&gt;where(function($q) use ($search) {
        $q-&gt;where('name', 'like', '%' . $search . '%')
          -&gt;orWhere('email', 'like', '%' . $search . '%')
          -&gt;orWhere('description', 'like', '%' . $search . '%');
    });
});
</code></code></pre><p>With this implementation, users can type "active users" to find all active users, or "pending" to find all pending records, while still maintaining the ability to search by name or email.</p><h3>3. Multi-Table Complex Search</h3><p>For more complex scenarios involving multiple related tables, you can implement sophisticated search logic:</p><pre><code><code>$this-&gt;hookSearch(function($query, $search) {
    $query-&gt;where(function($q) use ($search) {
        // Search in main table
        $q-&gt;where('orders.order_number', 'like', '%' . $search . '%')
          -&gt;orWhere('orders.notes', 'like', '%' . $search . '%')
          
          // Search in customer data
          -&gt;orWhereHas('customer', function($customerQuery) use ($search) {
              $customerQuery-&gt;where('name', 'like', '%' . $search . '%')
                           -&gt;orWhere('email', 'like', '%' . $search . '%')
                           -&gt;orWhere('phone', 'like', '%' . $search . '%');
          })
          
          // Search in product data through order items
          -&gt;orWhereHas('orderItems.product', function($productQuery) use ($search) {
              $productQuery-&gt;where('name', 'like', '%' . $search . '%')
                          -&gt;orWhere('sku', 'like', '%' . $search . '%');
          });
    });
});
</code></code></pre><p>This example demonstrates searching across orders, customers, and products all in one search query, providing users with incredibly powerful search capabilities.</p><h3>4. Date Range and Numeric Search</h3><p>You can implement smart parsing for date ranges and numeric comparisons:</p><pre><code><code>$this-&gt;hookSearch(function($query, $search) {
    // Check if search contains date patterns
    if (preg_match('/(\d{4}-\d{2}-\d{2})/', $search, $matches)) {
        $query-&gt;whereDate('created_at', $matches[1]);
        return;
    }
    
    // Check for price range searches (e.g., "price &gt; 100")
    if (preg_match('/price\s*([&gt;&lt;=]+)\s*(\d+)/', $search, $matches)) {
        $operator = $matches[1];
        $value = $matches[2];
        $query-&gt;where('price', $operator, $value);
        return;
    }
    
    // Check for numeric ID search
    if (is_numeric($search)) {
        $query-&gt;where('id', $search);
        return;
    }
    
    // Default text search
    $query-&gt;where(function($q) use ($search) {
        $q-&gt;where('name', 'like', '%' . $search . '%')
          -&gt;orWhere('description', 'like', '%' . $search . '%');
    });
});
</code></code></pre><h3>5. Geographic Search</h3><p>For applications dealing with location data, you can implement geographic search:</p><pre><code><code>$this-&gt;hookSearch(function($query, $search) {
    $query-&gt;where(function($q) use ($search) {
        $q-&gt;where('stores.name', 'like', '%' . $search . '%')
          -&gt;orWhere('stores.address', 'like', '%' . $search . '%')
          -&gt;orWhereHas('city', function($cityQuery) use ($search) {
              $cityQuery-&gt;where('name', 'like', '%' . $search . '%');
          })
          -&gt;orWhereHas('city.province', function($provinceQuery) use ($search) {
              $provinceQuery-&gt;where('name', 'like', '%' . $search . '%');
          });
    });
});
</code></code></pre><h2>Best Practices and Tips</h2><h3>1. Performance Considerations</h3><p>When implementing custom search logic, always consider performance:</p><pre><code><code>$this-&gt;hookSearch(function($query, $search) {
    // Use indexes - ensure your searchable columns are indexed
    $query-&gt;where(function($q) use ($search) {
        $q-&gt;where('indexed_column', 'like', '%' . $search . '%')
          -&gt;orWhere('another_indexed_column', 'like', '%' . $search . '%');
    });
});
</code></code></pre><h3>2. Input Sanitization</h3><p>Always sanitize user input to prevent SQL injection and other security issues:</p><pre><code><code>$this-&gt;hookSearch(function($query, $search) {
    // Clean the search term
    $cleanSearch = trim($search);
    $cleanSearch = preg_replace('/[^a-zA-Z0-9\s@.-]/', '', $cleanSearch);
    
    if (strlen($cleanSearch) &lt; 2) {
        return; // Don't search for terms that are too short
    }
    
    $query-&gt;where(function($q) use ($cleanSearch) {
        $q-&gt;where('name', 'like', '%' . $cleanSearch . '%')
          -&gt;orWhere('email', 'like', '%' . $cleanSearch . '%');
    });
});
</code></code></pre><h3>3. Combining Multiple hookSearch Calls</h3><p>You can call <code>hookSearch()</code> multiple times in the same <code>init()</code> method to add multiple search conditions:</p><pre><code><code>public function init(): void
{
    // Primary search logic
    $this-&gt;hookSearch(function($query, $search) {
        $query-&gt;where('name', 'like', '%' . $search . '%');
    });
    
    // Additional search conditions
    $this-&gt;hookSearch(function($query, $search) {
        if (str_contains(strtolower($search), 'urgent')) {
            $query-&gt;where('priority', 'high');
        }
    });
}
</code></code></pre><h3>4. Debugging Search Queries</h3><p>For debugging purposes, you can log the generated SQL queries:</p><pre><code><code>$this-&gt;hookSearch(function($query, $search) {
    $query-&gt;where(function($q) use ($search) {
        $q-&gt;where('name', 'like', '%' . $search . '%')
          -&gt;orWhere('email', 'like', '%' . $search . '%');
    });
    
    // Debug: Log the SQL query
    \Log::debug('Search Query: ' . $query-&gt;toSql());
    \Log::debug('Search Bindings: ', $query-&gt;getBindings());
});
</code></code></pre><h2>Real-World Example: E-commerce Product Search</h2><p>Let's put it all together with a comprehensive e-commerce product search implementation:</p><pre><code><code>&lt;?php

namespace App\Cb\Modules\Products\Livewire;

use CrudBooster\Livewire\BaseBrowseComponent;
use CrudBooster\Livewire\ColumnBuilder\Column;
use App\Models\Product;

class Products extends BaseBrowseComponent
{
    public $modelName = Product::class;
    
    public function init(): void
    {
        $this-&gt;makeColumns([
            Column::add(label: 'Name', key: 'name'),
            Column::add(label: 'SKU', key: 'sku'),
            Column::add(label: 'Price', key: 'price'),
            Column::add(label: 'Category', key: 'category.name'),
            Column::add(label: 'Brand', key: 'brand.name'),
        ]);
        
        $this-&gt;hookSearch(function($query, $search) {
            $searchLower = strtolower(trim($search));
            
            // Handle empty search
            if (empty($searchLower)) {
                return;
            }
            
            $query-&gt;where(function($q) use ($search, $searchLower) {
                // Basic product information
                $q-&gt;where('products.name', 'like', '%' . $search . '%')
                  -&gt;orWhere('products.sku', 'like', '%' . $search . '%')
                  -&gt;orWhere('products.description', 'like', '%' . $search . '%')
                  
                  // Search in category
                  -&gt;orWhereHas('category', function($categoryQuery) use ($search) {
                      $categoryQuery-&gt;where('name', 'like', '%' . $search . '%');
                  })
                  
                  // Search in brand
                  -&gt;orWhereHas('brand', function($brandQuery) use ($search) {
                      $brandQuery-&gt;where('name', 'like', '%' . $search . '%');
                  })
                  
                  // Search in product attributes
                  -&gt;orWhereHas('attributes', function($attributeQuery) use ($search) {
                      $attributeQuery-&gt;where('value', 'like', '%' . $search . '%');
                  });
            });
            
            // Handle status searches
            if (str_contains($searchLower, 'in stock') || str_contains($searchLower, 'available')) {
                $query-&gt;where('stock_quantity', '&gt;', 0);
            } elseif (str_contains($searchLower, 'out of stock') || str_contains($searchLower, 'unavailable')) {
                $query-&gt;where('stock_quantity', '&lt;=', 0);
            }
            
            // Handle price range searches
            if (preg_match('/under\s*\$?(\d+)/', $searchLower, $matches)) {
                $query-&gt;where('price', '&lt;', $matches[1]);
            } elseif (preg_match('/over\s*\$?(\d+)/', $searchLower, $matches)) {
                $query-&gt;where('price', '&gt;', $matches[1]);
            }
        });
    }
}
</code></code></pre><p>This implementation allows users to search for products in various ways:</p><ul><li><p>By product name, SKU, or description</p></li><li><p>By category or brand name</p></li><li><p>By product attributes</p></li><li><p>Using natural language like "in stock products"</p></li><li><p>Using price ranges like "under $50"</p></li></ul><h2>Conclusion</h2><p>The <code>hookSearch</code> feature in CRUDBooster provides developers with unprecedented control over search functionality. By implementing custom search logic, you can create intuitive, powerful search experiences that go far beyond simple column matching.</p><p>Key takeaways:</p><ul><li><p>Use <code>hookSearch</code> to implement complex search logic that the default search cannot handle</p></li><li><p>Always consider performance implications and use proper indexing</p></li><li><p>Sanitize user input to prevent security issues</p></li><li><p>Leverage Laravel's query builder features for complex relationships</p></li><li><p>Test your search logic thoroughly with various input scenarios</p></li></ul><p>Whether you're building a simple admin panel or a complex data management system, mastering the <code>hookSearch</code> feature will significantly enhance your users' ability to find and work with data efficiently.</p><p>The flexibility of <code>hookSearch</code> means that the only limit to your search functionality is your imagination. Start with simple implementations and gradually build more sophisticated search logic as your application's needs evolve.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Mastering CRUDBooster's Badgeable Feature: A Complete Developer Guide]]></title><description><![CDATA[Transform your data presentation with elegant and powerful badge systems]]></description><link>https://crudbooster.substack.com/p/mastering-crudboosters-badgeable</link><guid isPermaLink="false">https://crudbooster.substack.com/p/mastering-crudboosters-badgeable</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Wed, 09 Jul 2025 03:44:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Ebu8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ebu8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ebu8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png 424w, https://substackcdn.com/image/fetch/$s_!Ebu8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png 848w, https://substackcdn.com/image/fetch/$s_!Ebu8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!Ebu8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ebu8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png" width="1456" height="827" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/de8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:827,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1681132,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/167877024?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ebu8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png 424w, https://substackcdn.com/image/fetch/$s_!Ebu8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png 848w, https://substackcdn.com/image/fetch/$s_!Ebu8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!Ebu8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde8a802c-9ac0-427c-8dc5-a37759bb8db6_2056x1168.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Introduction</h2><p>Have you ever seen admin applications that display data status with attractive colors like "Active" with green background, "Pending" with yellow, or "Inactive" with red? This visual approach not only makes data easier to read but also significantly improves user experience. In CrudBooster v7.8.0+, this feature is called <strong>Badgeable</strong> - one of the most powerful and flexible features for enhancing data visualization in your admin panels.</p><p>The badgeable feature allows you to automatically transform plain text values into visually appealing badges with customizable colors, styles, and conditions. Whether you're building an e-commerce platform, content management system, or any data-driven application, badgeable can dramatically improve how your users interact with and understand your data.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>What is the Badgeable Feature?</h2><p>The badgeable feature in CrudBooster is an advanced column transformation system that automatically converts specific data values into styled badges. Instead of displaying plain text like "active", "pending", or "completed", badgeable renders these values as colorful, professional-looking badges that immediately convey status information to users.</p><p>This feature is built on top of TailwindCSS and provides consistent styling across your entire application. It supports multiple badge types, custom color schemes, conditional rendering, and even complex transformation logic.</p><h3>Key Benefits</h3><ul><li><p><strong>Enhanced Visual Communication</strong>: Status information becomes immediately recognizable</p></li><li><p><strong>Consistent Design</strong>: All badges follow the same design system</p></li><li><p><strong>Zero Configuration Required</strong>: Works out of the box with sensible defaults</p></li><li><p><strong>Highly Customizable</strong>: Support for custom colors, conditions, and transformations</p></li><li><p><strong>Performance Optimized</strong>: Minimal overhead on page load times</p></li><li><p><strong>Mobile Responsive</strong>: Badges look great on all screen sizes</p></li></ul><h2>System Requirements</h2><p>Before implementing badgeable features, ensure your CrudBooster installation meets these requirements:</p><ul><li><p><strong>CrudBooster v7.8.0 or higher</strong></p></li><li><p><strong>Laravel 11.x or 12.x</strong></p></li><li><p><strong>PHP 8.2+</strong></p></li><li><p><strong>TailwindCSS</strong> (included with CrudBooster)</p></li></ul><p>You can check your CrudBooster version by running:</p><pre><code><code>composer show crudbooster/crudbooster
</code></code></pre><h2>Basic Implementation</h2><p>Let's start with the simplest implementation of badgeable columns. Here's how to add a basic badgeable column to your browse component:</p><h3>Step 1: Basic Badgeable Setup</h3><pre><code><code>&lt;?php

namespace App\Cb\Modules\Products;

use CrudBooster\Livewire\BaseBrowseComponent;
use CrudBooster\Livewire\ColumnBuilder\Column;
use App\Models\Product;

class Products extends BaseBrowseComponent
{
    public $modelName = Product::class;
    
    public function init(): void
    {
        $this-&gt;makeColumns([
            Column::add('Product Name', 'name'),
            Column::add('Price', 'price'),
            Column::add('Status', 'status')-&gt;badgeable([
                'active' =&gt; 'success',
                'inactive' =&gt; 'danger',
                'pending' =&gt; 'warning',
            ]),
        ]);
    }
}
</code></code></pre><p>In this example, when the <code>status</code> column contains:</p><ul><li><p><code>'active'</code> &#8594; displays a green success badge</p></li><li><p><code>'inactive'</code> &#8594; displays a red danger badge</p></li><li><p><code>'pending'</code> &#8594; displays a yellow warning badge</p></li></ul><h3>Step 2: Understanding Badge Types</h3><p>CrudBooster provides five predefined badge types, each with its own color scheme:</p><p>Badge Type Color Use Case <code>success</code> Green Active states, completed tasks, approved items <code>danger</code> Red Inactive states, errors, rejected items <code>warning</code> Yellow/Orange Pending states, warnings, items needing attention <code>info</code> Blue Informational states, neutral information <code>primary</code> Purple/Indigo Default states, primary actions</p><h2>Advanced Badgeable Techniques</h2><h3>Individual Badge Methods</h3><p>For more granular control, you can use individual badge methods:</p><pre><code><code>public function init(): void
{
    $this-&gt;makeColumns([
        Column::add('Status', 'status')-&gt;badgeableSuccess('active', 'Active'),
        Column::add('Priority', 'priority')-&gt;badgeableDanger('high', 'High Priority'),
        Column::add('Category', 'category')-&gt;badgeableWarning('pending', 'Under Review'),
        Column::add('Type', 'type')-&gt;badgeableInfo('info', 'Information'),
        Column::add('Level', 'level')-&gt;badgeablePrimary('premium', 'Premium User'),
    ]);
}
</code></code></pre><h3>Complex Mapping with Multiple Values</h3><p>You can map multiple values to the same badge type:</p><pre><code><code>Column::add('Order Status', 'order_status')-&gt;badgeable([
    'completed' =&gt; 'success',
    'delivered' =&gt; 'success',
    'shipped' =&gt; 'success',
    'pending' =&gt; 'warning',
    'processing' =&gt; 'warning',
    'cancelled' =&gt; 'danger',
    'refunded' =&gt; 'danger',
    'draft' =&gt; 'info',
])
</code></code></pre><h3>Combining with Transform Functions</h3><p>For advanced scenarios, you can combine badgeable with transform functions:</p><pre><code><code>Column::add('Score', 'score')-&gt;transform(function($value) {
    if ($value &gt;= 90) return 'excellent';
    if ($value &gt;= 75) return 'good';
    if ($value &gt;= 60) return 'average';
    return 'poor';
})-&gt;badgeable([
    'excellent' =&gt; 'success',
    'good' =&gt; 'info',
    'average' =&gt; 'warning',
    'poor' =&gt; 'danger',
])
</code></code></pre><h2>Real-World Use Cases</h2><h3>E-Commerce Product Management</h3><pre><code><code>public function init(): void
{
    $this-&gt;makeColumns([
        Column::add('Product Name', 'name'),
        Column::add('SKU', 'sku'),
        Column::add('Stock Status', 'stock_status')-&gt;badgeable([
            'in_stock' =&gt; 'success',
            'low_stock' =&gt; 'warning',
            'out_of_stock' =&gt; 'danger',
            'backorder' =&gt; 'info',
        ]),
        Column::add('Visibility', 'visibility')-&gt;badgeable([
            'public' =&gt; 'success',
            'private' =&gt; 'danger',
            'draft' =&gt; 'warning',
        ]),
        Column::add('Featured', 'is_featured')-&gt;badgeable([
            '1' =&gt; 'primary',
            '0' =&gt; 'info',
        ]),
    ]);
}
</code></code></pre><h3>User Management System</h3><pre><code><code>public function init(): void
{
    $this-&gt;makeColumns([
        Column::add('Name', 'name'),
        Column::add('Email', 'email'),
        Column::add('Account Status', 'status')-&gt;badgeable([
            'active' =&gt; 'success',
            'suspended' =&gt; 'danger',
            'pending_verification' =&gt; 'warning',
            'inactive' =&gt; 'info',
        ]),
        Column::add('Subscription', 'subscription_type')-&gt;badgeable([
            'premium' =&gt; 'primary',
            'pro' =&gt; 'success',
            'basic' =&gt; 'info',
            'trial' =&gt; 'warning',
            'expired' =&gt; 'danger',
        ]),
    ]);
}
</code></code></pre><h3>Content Management</h3><pre><code><code>public function init(): void
{
    $this-&gt;makeColumns([
        Column::add('Title', 'title'),
        Column::add('Author', 'author_name'),
        Column::add('Publication Status', 'status')-&gt;badgeable([
            'published' =&gt; 'success',
            'draft' =&gt; 'warning',
            'scheduled' =&gt; 'info',
            'archived' =&gt; 'danger',
        ]),
        Column::add('Content Type', 'type')-&gt;badgeable([
            'article' =&gt; 'primary',
            'news' =&gt; 'info',
            'tutorial' =&gt; 'success',
            'announcement' =&gt; 'warning',
        ]),
    ]);
}
</code></code></pre><h3>Project Management</h3><pre><code><code>public function init(): void
{
    $this-&gt;makeColumns([
        Column::add('Project Name', 'name'),
        Column::add('Status', 'status')-&gt;badgeable([
            'completed' =&gt; 'success',
            'in_progress' =&gt; 'info',
            'on_hold' =&gt; 'warning',
            'cancelled' =&gt; 'danger',
        ]),
        Column::add('Priority', 'priority')-&gt;badgeable([
            'high' =&gt; 'danger',
            'medium' =&gt; 'warning',
            'low' =&gt; 'info',
        ]),
        Column::add('Health', 'health_status')-&gt;badgeable([
            'healthy' =&gt; 'success',
            'at_risk' =&gt; 'warning',
            'critical' =&gt; 'danger',
        ]),
    ]);
}
</code></code></pre><h2>Advanced Conditional Badging</h2><h3>Using transformWhen for Conditional Badges</h3><p>The <code>transformWhen</code> method allows you to apply badges only when specific conditions are met:</p><pre><code><code>Column::add('Revenue', 'monthly_revenue')
    -&gt;transformWhen(function($value) {
        return $value &gt; 10000;
    }, function($value) {
        return '&lt;span class="badge badge-success"&gt;High Performer&lt;/span&gt;';
    })
</code></code></pre><h3>Complex Conditional Logic</h3><pre><code><code>Column::add('Performance Score', 'score')-&gt;transformWithRow(function($row) {
    $score = $row-&gt;score;
    $department = $row-&gt;department;
    
    if ($department === 'sales' &amp;&amp; $score &gt;= 90) {
        return '&lt;span class="badge badge-primary"&gt;Star Performer&lt;/span&gt;';
    } elseif ($score &gt;= 85) {
        return '&lt;span class="badge badge-success"&gt;Excellent&lt;/span&gt;';
    } elseif ($score &gt;= 70) {
        return '&lt;span class="badge badge-info"&gt;Good&lt;/span&gt;';
    } elseif ($score &gt;= 60) {
        return '&lt;span class="badge badge-warning"&gt;Needs Improvement&lt;/span&gt;';
    } else {
        return '&lt;span class="badge badge-danger"&gt;Critical&lt;/span&gt;';
    }
})
</code></code></pre><h2>Best Practices and Tips</h2><h3>1. Consistent Color Coding</h3><p>Maintain consistent color meanings across your application:</p><pre><code><code>// Good: Consistent color usage
'active' =&gt; 'success',      // Always green for active states
'pending' =&gt; 'warning',     // Always yellow for pending states
'error' =&gt; 'danger',        // Always red for error states

// Avoid: Inconsistent color usage
'active' =&gt; 'success',      // Green for active
'enabled' =&gt; 'warning',     // Yellow for enabled (should be green)
</code></code></pre><h3>2. Meaningful Badge Text</h3><p>Use clear, descriptive text for better user experience:</p><pre><code><code>// Good: Clear and descriptive
Column::add('Status', 'status')-&gt;badgeable([
    'published' =&gt; 'success',
    'under_review' =&gt; 'warning',
    'rejected' =&gt; 'danger',
])

// Better: Even more descriptive with custom labels
Column::add('Status', 'status')-&gt;transformWithRow(function($row) {
    switch($row-&gt;status) {
        case 'published':
            return '&lt;span class="badge badge-success"&gt;&#10003; Published&lt;/span&gt;';
        case 'under_review':
            return '&lt;span class="badge badge-warning"&gt;&#9203; Under Review&lt;/span&gt;';
        case 'rejected':
            return '&lt;span class="badge badge-danger"&gt;&#10007; Rejected&lt;/span&gt;';
        default:
            return $row-&gt;status;
    }
})
</code></code></pre><h3>3. Performance Considerations</h3><p>For large datasets, consider the performance impact:</p><pre><code><code>// Efficient: Direct mapping
Column::add('Status', 'status')-&gt;badgeable([
    'active' =&gt; 'success',
    'inactive' =&gt; 'danger',
])

// Less efficient: Complex transformations on large datasets
Column::add('Status', 'status')-&gt;transformWithRow(function($row) {
    // Complex database queries or heavy computations
    $relatedData = SomeModel::where('id', $row-&gt;related_id)-&gt;first();
    // ... complex logic
})
</code></code></pre><h3>4. Accessibility Considerations</h3><p>Ensure your badges are accessible:</p><pre><code><code>// Include meaningful text for screen readers
Column::add('Status', 'status')-&gt;transformWithRow(function($row) {
    $statusText = ucfirst($row-&gt;status);
    return "&lt;span class=\"badge badge-success\" role=\"status\" aria-label=\"Status: {$statusText}\"&gt;{$statusText}&lt;/span&gt;";
})
</code></code></pre><h2>Troubleshooting Common Issues</h2><h3>Issue 1: Badges Not Displaying</h3><p><strong>Problem</strong>: Badges appear as plain text instead of styled badges.</p><p><strong>Solution</strong>: Ensure you're using CrudBooster v7.8.0+ and TailwindCSS is properly loaded:</p><pre><code><code>// Check your CrudBooster version
composer show crudbooster/crudbooster

// Ensure proper column setup
Column::add('Status', 'status')-&gt;badgeable([
    'active' =&gt; 'success',  // Make sure the key matches your data
])
</code></code></pre><h3>Issue 2: Wrong Colors Displayed</h3><p><strong>Problem</strong>: Badges show unexpected colors.</p><p><strong>Solution</strong>: Verify the badge type names and data values:</p><pre><code><code>// Correct badge types
'success', 'danger', 'warning', 'info', 'primary'

// Check your data values match the mapping
Column::add('Status', 'status')-&gt;badgeable([
    'active' =&gt; 'success',     // Ensure 'active' exists in your data
    'inactive' =&gt; 'danger',    // Ensure 'inactive' exists in your data
])
</code></code></pre><h3>Issue 3: Performance Issues</h3><p><strong>Problem</strong>: Page loads slowly with many badgeable columns.</p><p><strong>Solution</strong>: Optimize your queries and avoid complex transformations:</p><pre><code><code>// Optimize with eager loading
$this-&gt;hookQuery(function($query) {
    $query-&gt;with(['category', 'status']); // Eager load relationships
});

// Use simple badgeable instead of complex transforms
Column::add('Status', 'status')-&gt;badgeable([
    'active' =&gt; 'success',
    'inactive' =&gt; 'danger',
])
</code></code></pre><h2>Integration with Other CrudBooster Features</h2><h3>Combining with Filtering</h3><pre><code><code>public function init(): void
{
    $this-&gt;makeColumns([
        Column::add('Status', 'status')
            -&gt;badgeable([
                'active' =&gt; 'success',
                'inactive' =&gt; 'danger',
                'pending' =&gt; 'warning',
            ])
            -&gt;filterSelectEnum([
                'active' =&gt; 'Active',
                'inactive' =&gt; 'Inactive', 
                'pending' =&gt; 'Pending'
            ]),
    ]);
}
</code></code></pre><h3>Working with Relationships</h3><pre><code><code>public function init(): void
{
    $this-&gt;makeColumns([
        Column::add('Category Status', 'category.status')
            -&gt;relation('categories', function($join) {
                $join-&gt;on('categories.id', '=', 'products.category_id');
            }, 'status')
            -&gt;badgeable([
                'active' =&gt; 'success',
                'inactive' =&gt; 'danger',
            ]),
    ]);
}
</code></code></pre><h3>Export Compatibility</h3><p>Badgeable columns work seamlessly with CrudBooster's export features:</p><pre><code><code>public function init(): void
{
    $this-&gt;makeColumns([
        Column::add('Status', 'status')
            -&gt;badgeable([
                'active' =&gt; 'success',
                'inactive' =&gt; 'danger',
            ])
            -&gt;exportable(true), // Include in exports
    ]);
}
</code></code></pre><h2>Migration from Previous Versions</h2><p>If you're upgrading from an older CrudBooster version, here's how to migrate your existing badge implementations:</p><h3>Old Method (Pre v7.8.0)</h3><pre><code><code>// Old transform-based approach
Column::add('Status', 'status')-&gt;transform(function($value) {
    if ($value === 'active') {
        return '&lt;span class="label label-success"&gt;Active&lt;/span&gt;';
    }
    return '&lt;span class="label label-default"&gt;' . $value . '&lt;/span&gt;';
})
</code></code></pre><h3>New Method (v7.8.0+)</h3><pre><code><code>// New badgeable approach
Column::add('Status', 'status')-&gt;badgeable([
    'active' =&gt; 'success',
    'inactive' =&gt; 'danger',
])
</code></code></pre><h2>Conclusion</h2><p>The badgeable feature in CrudBooster represents a significant advancement in data visualization capabilities. By implementing the techniques covered in this guide, you can create more intuitive, visually appealing, and user-friendly admin interfaces.</p><p>Key takeaways:</p><ol><li><p><strong>Start Simple</strong>: Begin with basic badgeable implementations and gradually add complexity</p></li><li><p><strong>Stay Consistent</strong>: Use consistent color schemes across your application</p></li><li><p><strong>Think User Experience</strong>: Choose colors and labels that immediately convey meaning</p></li><li><p><strong>Optimize Performance</strong>: Use direct mapping over complex transformations when possible</p></li><li><p><strong>Consider Accessibility</strong>: Ensure your badges work for all users</p></li></ol><p>The badgeable feature transforms mundane data tables into engaging, informative dashboards that help users make quick decisions and understand data at a glance. As you implement these features in your projects, you'll find that they significantly improve both the aesthetic appeal and functional value of your admin panels.</p><p>Whether you're building an e-commerce platform, content management system, or any data-driven application, mastering the badgeable feature will elevate your CrudBooster implementations to professional standards that users will appreciate and enjoy using.</p><div><hr></div><p><em>Ready to implement badgeable features in your project? Start with the basic examples and gradually incorporate more advanced techniques as your requirements grow. The flexibility and power of CrudBooster's badgeable system will help you create outstanding admin interfaces that stand out from the crowd.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Tutorial: How to Customize the Detail Page of a Module in CRUDBooster]]></title><description><![CDATA[Hello developers!]]></description><link>https://crudbooster.substack.com/p/tutorial-how-to-customize-the-detail</link><guid isPermaLink="false">https://crudbooster.substack.com/p/tutorial-how-to-customize-the-detail</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Wed, 09 Apr 2025 04:45:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!xe0Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xe0Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xe0Z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg 424w, https://substackcdn.com/image/fetch/$s_!xe0Z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg 848w, https://substackcdn.com/image/fetch/$s_!xe0Z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!xe0Z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xe0Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:251418,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/160914388?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xe0Z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg 424w, https://substackcdn.com/image/fetch/$s_!xe0Z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg 848w, https://substackcdn.com/image/fetch/$s_!xe0Z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!xe0Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4efb23-c09a-40a4-aa0b-8e4347af0956_2560x1440.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Hello developers! &#128075; Yesterday I received a request from one of our members asking how to customize the detail page of a module in CRUDBooster. So, in this tutorial, I&#8217;ll walk you through the steps to do exactly that. Let&#8217;s dive in!</p><div><hr></div><h3><strong>Prerequisites</strong></h3><ul><li><p>CRUDBooster version <strong>v7.6.1 or higher</strong></p></li><li><p>Basic knowledge of <strong>Livewire</strong> and <strong>Blade</strong></p></li></ul><p>Make sure your CRUDBooster installation is already upgraded to version <strong>v7.6.1</strong> or above before following this tutorial.</p><p>In this guide, I&#8217;ll use a sample module called <strong>"Article"</strong>, and the goal is to only customize the detail page of this module while keeping everything else unchanged.</p><div><hr></div><h3><strong>1. Create a New Detail Template</strong></h3><p>First, create a <code>views</code> folder inside your target module directory:</p><pre><code><code>/app/Cb/Modules/Article/views</code></code></pre><p>Then, create a new file named <code>detail.blade.php</code> inside that folder. This will serve as the custom template for the detail page.</p><p>You can copy CRUDBooster&#8217;s default detail template and start modifying it as needed. Below is the base structure:</p><pre><code><code>@php use CrudBooster\Components\Icon\Icon; @endphp
&lt;div x-data="{openThumbnail: false, thumbnailSrc: ''}"&gt;
    &lt;livewire:alert-message :type="session('message_type') ?? $__alertType" :message="session('message') ?? $__alertMessage" :position="session('message_position') ?? $__alertPosition" /&gt;

    @if(isset($confirmTitle))
        {!! confirmMessageTag($confirmTitle, $confirmMessage, $confirmAction, $confirmButtonText, $confirmButtonColor) !!}
    @endif

    @if(!$formDialog)
        &lt;x-header :pageTitle="$pageTitle"/&gt;
        &lt;div class="my-4"&gt;
            &lt;a href="{{getCmsUrl($redirectBackPath)}}" wire:navigate class="text-sm text-gray-500 hover:text-sky-600"&gt;&amp;laquo; Go Back To List&lt;/a&gt;
        &lt;/div&gt;
    @endif

    &lt;div class="panel mb-4"&gt;
        &lt;div class="panel-header"&gt;
            &lt;div class="panel-header-title"&gt;
                &lt;h2&gt;Detail Data&lt;/h2&gt;
            &lt;/div&gt;
            &lt;div class="panel-header-action"&gt;
                @if(!$formDialog)
                    @can('update', $module['key'])
                        &lt;a title="Edit Data" href="{{getCmsUrl($module['key'])}}/{{$formId}}/edit?ref={{urlencode(url()-&gt;current())}}" wire:navigate&gt;
                            {!! Icon::PENCIL !!}
                        &lt;/a&gt;
                    @endcan
                @endif
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="panel-content"&gt;
            @cbDetailContent(['formColumns'=&gt; $formColumns, 'formData'=&gt; $formData])
            &lt;div class="w-full"&gt;
                &lt;div class="flex justify-end space-x-2"&gt;
                    &lt;a href="{{!$formDialog ? getCmsUrl($redirectBackPath) : "javascript:"}}" @if(!$formDialog) wire:navigate @else wire:click="$dispatch('closeFormDialog')" @endif class="btn btn-default"&gt;Cancel&lt;/a&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    @foreach($subModules as $subModule)
        @livewire($subModule['key'].'-browse', ['withHeader' =&gt; false, 'tableTitle' =&gt; $subModule['tableTitle'], 'formDialog'=&gt; true, 'moduleKey'=&gt; $subModule['key'], 'foreignKey'=&gt; $subModule['foreignKey'], 'foreignKeyValue'=&gt; $formId])
    @endforeach
&lt;/div&gt;
</code></code></pre><blockquote><p>&#9888;&#65039; Please note: CRUDBooster depends on certain logic inside this template. If you wish to customize it, do so without removing the essential parts and logic required for it to work correctly.</p></blockquote><div><hr></div><h3><strong>2. Register the View in Your Service Provider</strong></h3><p>Next, register your custom view namespace in your module&#8217;s service provider located at:</p><pre><code><code>/app/Cb/Modules/Article/ArticleServiceProvider.php</code></code></pre><p>Inside the <code>boot()</code> method, add the following:</p><pre><code><code>public function boot()
{
    $this-&gt;loadViewsFrom(__DIR__.'/views', 'article');
}
</code></code></pre><p>If you're unfamiliar with <code>loadViewsFrom</code>, you can check Laravel's documentation or ask ChatGPT for further clarification.</p><div><hr></div><h3><strong>3. Override the View in Your Form Component</strong></h3><p>Now go to your form component class:</p><pre><code><code>/app/Cb/Modules/Article/Livewire/ArticleForm.php
</code></code></pre><p>Add a new property <code>$viewDetail</code> to override the default CRUDBooster detail view:</p><pre><code><code>class ArticleForm extends BaseFormComponent
{
    public $pageTitle = "Article";
    protected $modelService = ArticleService::class;
    protected $modelName = ArticleModel::class;

    protected string $viewDetail = 'article::detail';
    //...
}
</code></code></pre><h3><strong>4. Add Custom Assets (CSS &amp; JS)</strong></h3><p>As an additional enhancement, you may also want to include your own custom CSS or JavaScript in your module. You can do this directly from the module&#8217;s service provider.</p><p>In the same <code>boot()</code> method, add the following lines:</p><pre><code><code>\CrudBooster\Themes\CbThemeAssetRegistrar::addCss('https://path-to-your-css-file.css');
\CrudBooster\Themes\CbThemeAssetRegistrar::addJs('https://path-to-your-js-file.js');</code></code></pre><p>This allows you to inject specific styles or scripts into your custom detail page (or other parts of the module) as needed.</p><h3>&#9989; <strong>Conclusion</strong></h3><p>And that&#8217;s it! &#127881; You've now learned how to override and customize the detail page view of a CRUDBooster module. This allows you to create a richer, more tailored presentation for your data without breaking the existing system.</p><p>With this technique, you can:</p><ul><li><p>Design your own UI for data detail pages</p></li><li><p>Add custom styling, layouts, or additional elements</p></li><li><p>Still keep full compatibility with CRUDBooster&#8217;s permission and routing logic</p></li></ul><p>Stay tuned for more tutorials, and if you have questions, feel free to reach out or join our community on <a href="https://discord.gg/gJVuxPE8">Discord</a>!</p><p><a href="https://crudbooster.com">Download CRUDBooster now</a> and take your Laravel development to the next level! Get 10% discounted by using promo code <strong>UPGRADE10</strong> (sshh this is limited slot&#8230;)</p><p>Happy coding! &#128640;</p>]]></content:encoded></item><item><title><![CDATA[Tutorial: Generate CRUD in Laravel with CRUDBooster]]></title><description><![CDATA[Only need 5 minutes]]></description><link>https://crudbooster.substack.com/p/tutorial-generate-crud-in-laravel</link><guid isPermaLink="false">https://crudbooster.substack.com/p/tutorial-generate-crud-in-laravel</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Mon, 17 Mar 2025 01:24:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!jL1Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jL1Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jL1Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!jL1Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!jL1Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!jL1Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jL1Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:102192,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159222142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jL1Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!jL1Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!jL1Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!jL1Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f7ae278-1a0c-4fd1-9b68-3c730b2d90a9_1280x720.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Have you ever thought about how much time it takes to create repetitive CRUD operations in Laravel? And let&#8217;s not forget that building a project often involves not just one or two modules, but potentially dozens of modules, all within a tight deadline. I know freelancers and software houses can relate to this a lot. But with CRUDBooster, you don&#8217;t have to worry about the boring task of creating CRUD operations. You can save up to 70% of your personal timeline and don&#8217;t have to stress about minor bugs like data saving errors or data deletion errors. CRUDBooster will take care of all that for you!</p><h2><strong>Prerequisites</strong></h2><ul><li><p>CRUDBooster v7.x is already installed in your Laravel project (if you don&#8217;t have it, please download it here).</p></li><li><p>Basic knowledge of Laravel.</p></li></ul><h2><strong>Installing Laravel (If doesn&#8217;t exists)</strong></h2><ol><li><p>Open the terminal in the &#8220;~/crud-laravel&#8221; folder, create it first if it doesn&#8217;t.<br><code>mkdir ~/crud-laravel &amp;&amp; cd ~/crud-laravel</code></p></li><li><p>Run the following command:<br><code>composer create-project laravel/laravel=&#8221;^12.0&#8221; crudbooster</code></p></li></ol><blockquote><p>Check this out this <a href="https://laravel.com/docs/12.x/installation">link</a> for more information about Laravel installation </p></blockquote><h2><strong>Installing CRUDBooster</strong></h2><ol><li><p>Checkout a new license at https://crudbooster.com/ (You may choose Trial if you want to try purpose)</p></li><li><p>Add this bellow composer config repository at laravel project ~/crud-laravel/crudbooster<br><code>composer config repositories.crudbooster vcs https://xxx@repo.crudbooster.com/crudbooster/crudbooster.git</code><br>&gt; Replace &#8220;xxx&#8221; with a code your own (check your crudbooster email regarding project active email)</p></li><li><p>Run this bellow &#8220;composer require&#8221; at laravel project ~/crud-laravel/crudbooster to start install crudbooster:<br><code>composer require crudbooster/crudbooster:&#8221;^7.4&#8221; -W</code></p></li><li><p>Follow the install steps at terminal screen, it start with enter your license key. It&#8217;s very easy, if you have a question, I like to help, drop your comment bellow. </p></li></ol><h2><strong>Generating CRUD with Artisan CLI</strong></h2><p>Creating CRUD with the Artisan CLI is a very quick method because in general you only need to write the Artisan command, and the CRUD module will be generated immediately. Here&#8217;s how to use it:</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><ol><li><p>For prerequisite, please ensure you have a table with already fields inside. Or, please create it first, following this bellow structure:<br><strong>table</strong>: posts<br><strong>structure</strong>:<br>- id (bigint primary key)<br>- created_at (timestamp)<br>- updated_at (timestamp)<br>- deleted_at (timestamp)<br>- title (varchar 255)<br>- content (longtext)<br>- published_at (datetime)</p></li><li><p>Open the terminal in your Laravel project.</p></li><li><p>Run following command to create a module:<br><code>php artisan cb:crud posts</code></p></li></ol><p>Great job! You can now access your new CRUD module called "Posts." Just log in to CRUDBooster at <strong>http://localhost:8000/cms/auth/login</strong> and click on the new menu item labeled "Posts." Enjoy exploring!</p><blockquote><p>Want to know more about command crud? Check out this link: https://crudbooster.com/docs#/?id=via-command-line</p></blockquote><h2><strong>Generating CRUD with GUI</strong></h2><p>For those of you who prefer not to write any code, you&#8217;re in for a treat! With CRUDBooster, you can create a CRUD module with just a click&#8212;no coding required! It even generates a table for you automatically, so you don&#8217;t have to define the table beforehand. Enjoy the simplicity!</p><ol><li><p>Login to your CRUDBooster (http://localhost:8000/cms/auth/login)</p></li><li><p>Go to menu &#8220;Module Builder&#8221;</p></li><li><p>Click on &#8220;Add Module Builder&#8221; button</p></li><li><p>Please fill out the form with the following information, and then click 'Save':</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_YHg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_YHg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png 424w, https://substackcdn.com/image/fetch/$s_!_YHg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png 848w, https://substackcdn.com/image/fetch/$s_!_YHg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png 1272w, https://substackcdn.com/image/fetch/$s_!_YHg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_YHg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png" width="1456" height="926" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:926,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:345551,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159222142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_YHg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png 424w, https://substackcdn.com/image/fetch/$s_!_YHg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png 848w, https://substackcdn.com/image/fetch/$s_!_YHg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png 1272w, https://substackcdn.com/image/fetch/$s_!_YHg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbde54df6-af2e-44a2-a3c6-c7e04c827ba7_2520x1602.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li><li><p>Add some fields to the Database Builder. Enter the column/field name and then click the '+' button. Keep trying until all fields are added! and lastly Click &#8220;Save&#8221;.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NOFX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NOFX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png 424w, https://substackcdn.com/image/fetch/$s_!NOFX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png 848w, https://substackcdn.com/image/fetch/$s_!NOFX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png 1272w, https://substackcdn.com/image/fetch/$s_!NOFX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NOFX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png" width="1456" height="926" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:926,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:306928,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159222142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NOFX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png 424w, https://substackcdn.com/image/fetch/$s_!NOFX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png 848w, https://substackcdn.com/image/fetch/$s_!NOFX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png 1272w, https://substackcdn.com/image/fetch/$s_!NOFX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f66539-b089-4094-a45c-dccb4978d43e_2520x1602.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li><li><p>Then, you can click &#8220;Re/Build Module&#8221; button directly, without fill out all menu (Relationship, Query Condition, Browse, etc) first. </p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WCP5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WCP5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png 424w, https://substackcdn.com/image/fetch/$s_!WCP5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png 848w, https://substackcdn.com/image/fetch/$s_!WCP5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png 1272w, https://substackcdn.com/image/fetch/$s_!WCP5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WCP5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png" width="672" height="204" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:204,&quot;width&quot;:672,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29366,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159222142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WCP5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png 424w, https://substackcdn.com/image/fetch/$s_!WCP5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png 848w, https://substackcdn.com/image/fetch/$s_!WCP5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png 1272w, https://substackcdn.com/image/fetch/$s_!WCP5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2896d7c3-1d16-47cf-a6b2-922a62f5047b_672x204.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div></li><li><p>Click &#8220;Yes&#8221; on build module confirmation</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SWIU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SWIU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png 424w, https://substackcdn.com/image/fetch/$s_!SWIU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png 848w, https://substackcdn.com/image/fetch/$s_!SWIU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png 1272w, https://substackcdn.com/image/fetch/$s_!SWIU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SWIU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png" width="1106" height="518" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:518,&quot;width&quot;:1106,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:88919,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159222142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SWIU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png 424w, https://substackcdn.com/image/fetch/$s_!SWIU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png 848w, https://substackcdn.com/image/fetch/$s_!SWIU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png 1272w, https://substackcdn.com/image/fetch/$s_!SWIU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae9f5cf4-52e4-4ce9-9057-71746f1d4b1a_1106x518.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li><li><p>You have done, you will see a new menu on the sidebar labeled &#8220;Posts&#8221;. Now let&#8217;s try by clicking it&#8217;s menu. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Cp2Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Cp2Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png 424w, https://substackcdn.com/image/fetch/$s_!Cp2Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png 848w, https://substackcdn.com/image/fetch/$s_!Cp2Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png 1272w, https://substackcdn.com/image/fetch/$s_!Cp2Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Cp2Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png" width="1456" height="610" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:610,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:226732,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159222142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Cp2Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png 424w, https://substackcdn.com/image/fetch/$s_!Cp2Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png 848w, https://substackcdn.com/image/fetch/$s_!Cp2Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png 1272w, https://substackcdn.com/image/fetch/$s_!Cp2Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81f3e226-50dc-4f98-aa68-ab9fe6d48105_3018x1264.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Voila, great you have a new crud module labeled &#8220;Posts&#8221; that you have create by using GUI. </p></li><li><p>Explore on other feature like Add data, Edit and Delete data<br><br><strong>Add Form</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!b23L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!b23L!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png 424w, https://substackcdn.com/image/fetch/$s_!b23L!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png 848w, https://substackcdn.com/image/fetch/$s_!b23L!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!b23L!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!b23L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png" width="1456" height="732" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:732,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:131934,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159222142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!b23L!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png 424w, https://substackcdn.com/image/fetch/$s_!b23L!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png 848w, https://substackcdn.com/image/fetch/$s_!b23L!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!b23L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2b16ba-c266-4a8b-9f89-7d679be8e463_2506x1260.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Browse</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lJa5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lJa5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png 424w, https://substackcdn.com/image/fetch/$s_!lJa5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png 848w, https://substackcdn.com/image/fetch/$s_!lJa5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!lJa5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lJa5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png" width="1456" height="732" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:732,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:141470,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159222142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lJa5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png 424w, https://substackcdn.com/image/fetch/$s_!lJa5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png 848w, https://substackcdn.com/image/fetch/$s_!lJa5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!lJa5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe55baedd-73eb-4223-8f5a-e551426290b0_2506x1260.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Edit</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4UtZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4UtZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png 424w, https://substackcdn.com/image/fetch/$s_!4UtZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png 848w, https://substackcdn.com/image/fetch/$s_!4UtZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!4UtZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4UtZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png" width="1456" height="732" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:732,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:131471,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159222142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4UtZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png 424w, https://substackcdn.com/image/fetch/$s_!4UtZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png 848w, https://substackcdn.com/image/fetch/$s_!4UtZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!4UtZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13536779-ac67-42e1-a465-b28131ced1ab_2506x1260.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Delete</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fxRS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fxRS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png 424w, https://substackcdn.com/image/fetch/$s_!fxRS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png 848w, https://substackcdn.com/image/fetch/$s_!fxRS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!fxRS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fxRS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png" width="1456" height="732" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:732,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:265153,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159222142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fxRS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png 424w, https://substackcdn.com/image/fetch/$s_!fxRS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png 848w, https://substackcdn.com/image/fetch/$s_!fxRS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!fxRS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F980150c1-d98e-46b3-bfbe-5626949c610e_2506x1260.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Detail Data</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-nic!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-nic!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png 424w, https://substackcdn.com/image/fetch/$s_!-nic!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png 848w, https://substackcdn.com/image/fetch/$s_!-nic!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!-nic!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-nic!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png" width="1456" height="732" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:732,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:110268,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159222142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-nic!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png 424w, https://substackcdn.com/image/fetch/$s_!-nic!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png 848w, https://substackcdn.com/image/fetch/$s_!-nic!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!-nic!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b406e45-a807-49e1-8569-05e1c7677ecc_2506x1260.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li></ol><h2><strong>Conclusion</strong></h2><p>By following this tutorial, you&#8217;ve learned how to efficiently create a <strong>CRUD module</strong> in Laravel using <strong>CRUDBooster</strong>. Whether using the <strong>command-line interface (CLI)</strong> or the <strong>graphical user interface (GUI)</strong>, CRUDBooster streamlines the process, saving valuable development time.</p><p>With its powerful features and intuitive tools, CRUDBooster allows developers to focus more on building functionality rather than repetitive CRUD operations. Now, you&#8217;re equipped to speed up your <strong>Laravel backend development</strong> with ease. &#128640;</p><p>Ready to take it further? Try building more complex modules and customize them to fit your project&#8217;s needs! Download <a href="https://crudbooster.com">CRUDBooster</a> Now!</p><blockquote><p>Stay tuned for an even more detailed tutorial in the next one! If you haven&#8217;t already, subscribe to this substack to get all the latest updates.</p></blockquote><p></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Tutorial: Creating a Custom Module in CRUDBooster]]></title><description><![CDATA[In this tutorial, I will guide you through the process of creating a custom module in CRUDBooster.]]></description><link>https://crudbooster.substack.com/p/tutorial-creating-a-custom-module</link><guid isPermaLink="false">https://crudbooster.substack.com/p/tutorial-creating-a-custom-module</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Sat, 15 Mar 2025 00:10:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!94Z8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!94Z8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!94Z8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png 424w, https://substackcdn.com/image/fetch/$s_!94Z8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png 848w, https://substackcdn.com/image/fetch/$s_!94Z8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png 1272w, https://substackcdn.com/image/fetch/$s_!94Z8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!94Z8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:999561,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159101747?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!94Z8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png 424w, https://substackcdn.com/image/fetch/$s_!94Z8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png 848w, https://substackcdn.com/image/fetch/$s_!94Z8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png 1272w, https://substackcdn.com/image/fetch/$s_!94Z8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c83e545-46d8-465c-a62e-3c770de16b79_1600x900.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In this tutorial, I will guide you through the process of creating a custom module in CRUDBooster. We will discuss why and when you might need to create a custom module, as well as how to integrate it with CRUDBooster's Authorization and Permission system.</p><p>By default, CRUDBooster provides a powerful CRUD generator that helps developers create admin panels quickly. However, in some cases, you may need a more customized approach that goes beyond the standard module generator. This is where custom modules come into play. With a custom module, you can design unique workflows, tailor the UI/UX to your needs, and extend CRUDBooster&#8217;s functionality while still utilizing its robust authentication and authorization features.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Let&#8217;s dive into the step-by-step process of building a custom module.</p><blockquote><p>This tutorial is based on the official documentation: <a href="https://crudbooster.com/docs#/?id=custom-module">https://crudbooster.com/docs#/?id=custom-module</a></p></blockquote><h3><strong>Prerequisites</strong></h3><ol><li><p>CRUDBooster v7.x installed on your Laravel project.</p></li><li><p>Basic knowledge of Livewire &amp; Laravel (<a href="https://livewire.laravel.com/">https://livewire.laravel.com/</a>)</p></li></ol><h2><strong>1. Understanding the Module Folder Structure</strong></h2><p>Before we start coding, let's understand the structure of a CRUDBooster module. Here&#8217;s what a module folder looks like:</p><pre><code><code>/app/Cb/Modules/YourModuleName

YourModuleName
|
--- Database
------ Migrations
--------- file_name_migration.php
--- Livewire
------ Name.php
--- Models
------ Name.php
--- Services
------ NameService.php
--- views
--- ModuleServiceProvider.php
--- router.php
</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!X-wc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!X-wc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png 424w, https://substackcdn.com/image/fetch/$s_!X-wc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png 848w, https://substackcdn.com/image/fetch/$s_!X-wc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png 1272w, https://substackcdn.com/image/fetch/$s_!X-wc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!X-wc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png" width="484" height="529.6873156342183" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:742,&quot;width&quot;:678,&quot;resizeWidth&quot;:484,&quot;bytes&quot;:75174,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159101747?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!X-wc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png 424w, https://substackcdn.com/image/fetch/$s_!X-wc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png 848w, https://substackcdn.com/image/fetch/$s_!X-wc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png 1272w, https://substackcdn.com/image/fetch/$s_!X-wc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F718e7b6d-82e4-46b3-af13-d491f085c862_678x742.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Modules should be placed inside <code>/app/Cb/Modules/{moduleName}</code>. The folder consists of:</p><ul><li><p><strong>Database</strong>: Stores migration files.</p></li><li><p><strong>Livewire</strong>: Contains Livewire components.</p></li><li><p><strong>Models</strong>: Houses Eloquent models.</p></li><li><p><strong>Services</strong>: Used for advanced query handling.</p></li><li><p><strong>Views</strong>: Contains Blade templates.</p></li><li><p><strong>ModuleServiceProvider</strong>: Registers the module.</p></li><li><p><strong>router.php</strong>: Defines custom routes.</p></li></ul><p>Having a well-structured module ensures better maintainability and scalability in your Laravel application.</p><blockquote><p>Let&#8217;s collaborate on this. Follow me as I create a folder named <strong>/app/Cb/Modules/CustomUser.</strong> Inside this folder, we&#8217;ll create another directory with the same structure as mentioned above.</p></blockquote><h2><strong>2, Creating the Livewire Component</strong></h2><p>Please create a file named &#8220;CustomUser.php&#8221; in the folder &#8220;Livewire.&#8221; Then, follow the code below:</p><pre><code>&lt;?php

namespace App\Cb\Modules\CustomUser\Livewire;

use App\Cb\Modules\User\Models\User;
use Illuminate\Support\Facades\Gate;
use Livewire\Component;

class CustomUser extends Component
{
    public function mount()
    {

    }

    public function render()
    {
        return view('cb.modules.customuser::index')
            -&gt;layout("cb.themes::layout-app");
    }

}</code></pre><p>We need to extend the view with the layout from CRUDBooster, using the layout name &#8220;cb.themes::layout-app&#8221;.</p><h2>3. Creating the View</h2><p>Create a file view name &#8220;index.blade.php&#8221; in the views folder </p><pre><code>&lt;div x-data="customUser()"&gt;
    
&lt;/div&gt;
&lt;script&gt;
    function customUser()
    {

    }
&lt;/script&gt;
</code></pre><p>This is a default template provided by Livewire&#8217;s standard library.</p><h2><strong>4. Creating the Service Provider</strong></h2><p>Each module requires a <strong>Service Provider</strong> to register itself with CRUDBooster. This acts as the module's entry point, ensuring it integrates seamlessly with the system. Here&#8217;s an example:</p><p><strong>File:</strong> <code>/app/Cb/Modules/CustomUser/CustomUserServiceProvider.php</code></p><pre><code><code>&lt;?php

namespace App\Cb\Modules\CustomUser;

use App\Cb\Modules\CustomUser\Livewire\CustomUser;
use CrudBooster\Modules\ModuleRegistrar;
use CrudBooster\Modules\Role\Enum\RolePermission;
use Illuminate\Support\ServiceProvider;
use Livewire\Livewire;

class CustomUserServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this-&gt;loadViewsFrom(__DIR__.'/views', 'cb.modules.customuser');
        $this-&gt;loadRoutesFrom(__DIR__ . '/router.php');

        Livewire::component('custom-user', CustomUser::class);
        ModuleRegistrar::registerModule(
            key: 'custom-user',
            name: 'Custom',
            browseModuleClass: CustomUser::class,
            formModuleClass: CustomUser::class,
            serviceProvider: self::class,
            additional: [
                'permissionAvailable' =&gt; [
                    RolePermission::READ,
                ],
            ]
        );
    }
}
</code></code></pre><p>Next, register this service provider in Laravel&#8217;s default <code>AppServiceProvider.php</code>:<br>at <strong>register</strong> method:</p><pre><code><code>$this-&gt;app-&gt;register(CustomUserServiceProvider::class);</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VdyJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VdyJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png 424w, https://substackcdn.com/image/fetch/$s_!VdyJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png 848w, https://substackcdn.com/image/fetch/$s_!VdyJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png 1272w, https://substackcdn.com/image/fetch/$s_!VdyJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VdyJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png" width="520" height="314.6" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:726,&quot;width&quot;:1200,&quot;resizeWidth&quot;:520,&quot;bytes&quot;:107077,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159101747?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VdyJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png 424w, https://substackcdn.com/image/fetch/$s_!VdyJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png 848w, https://substackcdn.com/image/fetch/$s_!VdyJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png 1272w, https://substackcdn.com/image/fetch/$s_!VdyJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca0af55-c369-4e2f-83d7-822acca301f2_1200x726.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>5. Defining Custom Routes</strong></h2><p>Modules often require custom routes to handle their operations. Inside <code>router.php</code>, define your module&#8217;s route:</p><pre><code><code>&lt;?php
\CrudBooster\Helpers\CBRoute::createRouteOne("custom-user", \App\Cb\Modules\CustomUser\Livewire\CustomUser::class);
</code></code></pre><p>This ensures that the module is accessible via the <code>/cms/custom-user</code> URL.</p><h2><strong>6. Initial Testing</strong></h2><p>After following the steps above, you can test your module by navigating to:</p><pre><code><code>https://localhost:8000/cms/custom-user
</code></code></pre><blockquote><p>Ensure your Laravel development server is running (<code>php artisan serve</code>).</p></blockquote><p>If everything is set up correctly, you should see your module&#8217;s page load without issues.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!A1J2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!A1J2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png 424w, https://substackcdn.com/image/fetch/$s_!A1J2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png 848w, https://substackcdn.com/image/fetch/$s_!A1J2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png 1272w, https://substackcdn.com/image/fetch/$s_!A1J2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!A1J2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png" width="1456" height="778" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:778,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:129483,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159101747?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!A1J2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png 424w, https://substackcdn.com/image/fetch/$s_!A1J2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png 848w, https://substackcdn.com/image/fetch/$s_!A1J2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png 1272w, https://substackcdn.com/image/fetch/$s_!A1J2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa111d919-9390-4a53-b823-abe0221b11f8_2164x1156.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>7. Enhancing the View &amp; Component Class</strong></h2><p>Now, let&#8217;s add some structure to the UI. We will create a simple table displaying user data:</p><p>Component Class (app/Cb/Modules/CustomUser/Livewire/CustomUser.php)</p><pre><code>&lt;?php

namespace App\Cb\Modules\CustomUser\Livewire;

use App\Cb\Modules\User\Models\User;
use Illuminate\Support\Facades\Gate;
use Livewire\Component;

class CustomUser extends Component
{
    public function mount()
    {

    }

    public function render()
    {
        return view('cb.modules.customuser::index',[
            'users'=&gt; User::<em>all</em>()
        ])
            -&gt;layout("cb.themes::layout-app");
    }

}</code></pre><p>View (app/Cb/Modules/CustomUser/views/index.blade.php)</p><pre><code><code>&lt;div x-data="customUser()"&gt;
    &lt;div class="mb-4"&gt;
        &lt;x-header pageTitle="Custom User"/&gt;
    &lt;/div&gt;

    &lt;div class="flex justify-start mb-4"&gt;
        &lt;a href="javascript:" class="btn btn-primary"&gt;Add Data&lt;/a&gt;
    &lt;/div&gt;

    &lt;table class="table"&gt;
        &lt;thead&gt;
            &lt;tr&gt;
                &lt;th&gt;ID&lt;/th&gt;
                &lt;th&gt;Name&lt;/th&gt;
                &lt;th&gt;Email&lt;/th&gt;
                &lt;th&gt;Action&lt;/th&gt;
            &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
            @foreach($users as $user)
            &lt;tr&gt;
                &lt;td&gt;{{$user-&gt;id}}&lt;/td&gt;
                &lt;td&gt;{{$user-&gt;name}}&lt;/td&gt;
                &lt;td&gt;{{$user-&gt;email}}&lt;/td&gt;
                &lt;td class="flex justify-start gap-2"&gt;
                    &lt;a href="#" class="btn btn-outline-success"&gt;Edit&lt;/a&gt;
                    &lt;a href="#" class="btn btn-outline-danger"&gt;Delete&lt;/a&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
            @endforeach
        &lt;/tbody&gt;
    &lt;/table&gt;
&lt;/div&gt;
&lt;script&gt;
    function customUser() {}
&lt;/script&gt;
</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VS90!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VS90!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png 424w, https://substackcdn.com/image/fetch/$s_!VS90!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png 848w, https://substackcdn.com/image/fetch/$s_!VS90!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png 1272w, https://substackcdn.com/image/fetch/$s_!VS90!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VS90!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png" width="1456" height="609" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:609,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:199930,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/159101747?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VS90!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png 424w, https://substackcdn.com/image/fetch/$s_!VS90!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png 848w, https://substackcdn.com/image/fetch/$s_!VS90!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png 1272w, https://substackcdn.com/image/fetch/$s_!VS90!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71fb1b1b-2acb-472a-8e70-e6067e0c1f0e_3022x1264.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>8. Adding Permissions and Security</strong></h2><p>For security, always check user permissions before allowing actions. You can enforce access control using Blade directives:</p><p><code>@can(&#8220;{permission}&#8221;,&#8221;{module-key}&#8221;)</code></p><pre><code><code>@can('create', 'customer-user')
  &lt;a href="javascript:" class="btn btn-primary"&gt;Add Data&lt;/a&gt;
@endcan
</code></code></pre><p>Or, inside a controller:</p><pre><code>use Illuminate\Support\Facades\Gate;

Gate::check(&#8216;{permission}&#8217;, &#8216;{module-key}&#8217;);</code></pre><p>Example:</p><pre><code><code>if (!Gate::check('create', 'customer-user')) {
    abort(403);
}
</code></code></pre><blockquote><p>Permission available: create, read, update, delete, is_super_admin</p></blockquote><h3><strong>9. Adding a Custom CSS &amp; JS</strong></h3><p>If you want to add a custom CSS, you can embed your CSS file in crudbooster. To do this, use the following function and send it to the service provider. In this context, the service provider is CustomUserServiceProvider, and you should call it in the boot method:</p><pre><code>// Register custom css
CbThemeAssetRegistrar::<em>addCss</em>(asset('css/custom-user-style.css'));</code></pre><p>Full version:</p><pre><code>&lt;?php

namespace App\Cb\Modules\CustomUser;

use App\Cb\Modules\CustomUser\Livewire\CustomUser;
use CrudBooster\Modules\ModuleRegistrar;
use CrudBooster\Modules\Role\Enum\RolePermission;
use CrudBooster\Themes\CbThemeAssetRegistrar;
use Illuminate\Support\ServiceProvider;
use Livewire\Livewire;

class CustomUserServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this-&gt;loadViewsFrom(<em>__DIR__</em>.'/views', 'cb.modules.customuser');
        $this-&gt;loadRoutesFrom(<em>__DIR__ </em>. '/router.php');

        Livewire::component('custom-user', CustomUser::class);
        ModuleRegistrar::<em>registerModule</em>(
            key: 'custom-user',
            name: 'Custom',
            browseModuleClass: CustomUser::class,
            formModuleClass: CustomUser::class,
            serviceProvider: self::class,
            additional: [
                'permissionAvailable' =&gt; [
                    RolePermission::<em>READ</em>,
                ],
        ]);

        <code>// Register custom css
        CbThemeAssetRegistrar::addCss(asset('css/custom-user-style.css'));</code>
    }
}</code></pre><p>Now, if you want to add JavaScript, the process is similar to adding CSS, but the functions you can use are different.</p><pre><code><code>// Register custom js
CbThemeAssetRegistrar::addJs(asset('js/custom-user-script.js'));</code></code></pre><h3><strong>10. Add to Menu</strong></h3><p>Once you have successfully created the module, it's time to add it to the menu for easy access. Follow these steps:</p><ol><li><p>Go to the <strong>Menu Management</strong> section.</p></li><li><p>Click <strong>"Add Menu Management"</strong>.</p></li><li><p>Fill out the form, select <strong>CRUD Module</strong> as the type, and choose the <strong>Custom</strong> module from the list. (This is the module you just created, and it should now appear in the list.)</p></li><li><p>Click <strong>"Save"</strong> to apply the changes.</p></li></ol><h2><strong>Conclusion</strong></h2><p>By following this guide, you have successfully built a custom module in CRUDBooster. This allows you to extend the core functionality while maintaining security and flexibility. You can now: <br>&#9989; Create custom Livewire components. <br>&#9989; Register and configure modules via a service provider. <br>&#9989; Define custom routes and manage views. <br>&#9989; Secure your module with CRUDBooster&#8217;s built-in permission system.</p><p>Start building your own modules today and take your Laravel admin panel to the next level! &#128640; Download <strong><a href="https://crudbooster.com/?utm=substack.com">CRUDBooster</a></strong> now!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Tutorial: Creating Charts with CRUDBooster Page Builder]]></title><description><![CDATA[In this tutorial, we&#8217;ll explore how to create charts in CRUDBooster using the Page Builder feature.]]></description><link>https://crudbooster.substack.com/p/tutorial-creating-charts-with-crudbooster</link><guid isPermaLink="false">https://crudbooster.substack.com/p/tutorial-creating-charts-with-crudbooster</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Wed, 12 Mar 2025 12:37:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!0uhQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0uhQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0uhQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0uhQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0uhQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0uhQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0uhQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:149993,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/158909717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0uhQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0uhQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0uhQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0uhQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c52f17-c047-4305-9612-fc42b9ae1b29_1600x900.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In this tutorial, we&#8217;ll explore how to create charts in CRUDBooster using the Page Builder feature.</p><p>Page Builder is a powerful feature in CRUDBooster that allows you to create custom module pages effortlessly. You can design your own layout, add various elements, and include charts&#8212;all with a simple drag-and-drop interface.</p><p>Let&#8217;s dive into the step-by-step process of building a chart using Page Builder in CRUDBooster.</p><h3><strong>Case Study: Visualizing Member Growth Data (2024)</strong></h3><p>In this example, we&#8217;ll create a chart to display <strong>monthly member growth data for 2024</strong>.</p><h3><strong>Prerequisites</strong></h3><ol><li><p>CRUDBooster v7 installed on your Laravel project.</p></li><li><p>Member data for the year 2024 (adjust according to your dataset). (Click <strong><a href="https://drive.google.com/file/d/1-0V3Kcr0YcQVqwfxSz1_ayyejdBW_w0u/view?usp=sharing">here</a></strong> download dummy member data).</p></li></ol><h3><strong>Step 1: Accessing Page Builder</strong></h3><ol><li><p>Open the <strong>Page Builder</strong> and enter the page name.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-peX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-peX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png 424w, https://substackcdn.com/image/fetch/$s_!-peX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png 848w, https://substackcdn.com/image/fetch/$s_!-peX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png 1272w, https://substackcdn.com/image/fetch/$s_!-peX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-peX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png" width="1456" height="874" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:874,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:133517,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/158909717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-peX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png 424w, https://substackcdn.com/image/fetch/$s_!-peX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png 848w, https://substackcdn.com/image/fetch/$s_!-peX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png 1272w, https://substackcdn.com/image/fetch/$s_!-peX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd37af6f1-2be4-4519-b3c4-64d1527a57a7_2510x1506.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p></li><li><p>Click the <strong>pencil icon</strong> at the bottom right to enter the workspace.</p><p><em>(Embed image: Edit Button)</em></p></li></ol><h3><strong>Step 2: Setting Up the Layout</strong></h3><ul><li><p>This is where we add elements to the page.</p></li><li><p>First, <strong>drag a Layout Column</strong> element into the workspace.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TDnE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TDnE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png 424w, https://substackcdn.com/image/fetch/$s_!TDnE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png 848w, https://substackcdn.com/image/fetch/$s_!TDnE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png 1272w, https://substackcdn.com/image/fetch/$s_!TDnE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TDnE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png" width="1456" height="620" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:620,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:165738,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/158909717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TDnE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png 424w, https://substackcdn.com/image/fetch/$s_!TDnE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png 848w, https://substackcdn.com/image/fetch/$s_!TDnE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png 1272w, https://substackcdn.com/image/fetch/$s_!TDnE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e84ab85-8938-47d9-aa4b-ac500286f83b_2992x1274.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p></li></ul><h3><strong>Step 3: Adding the Chart Element</strong></h3><ol><li><p>Select the <strong>Chart.js</strong> element from the sidebar.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!q_yH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!q_yH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png 424w, https://substackcdn.com/image/fetch/$s_!q_yH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png 848w, https://substackcdn.com/image/fetch/$s_!q_yH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png 1272w, https://substackcdn.com/image/fetch/$s_!q_yH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!q_yH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png" width="402" height="318.293059125964" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:616,&quot;width&quot;:778,&quot;resizeWidth&quot;:402,&quot;bytes&quot;:48161,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/158909717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!q_yH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png 424w, https://substackcdn.com/image/fetch/$s_!q_yH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png 848w, https://substackcdn.com/image/fetch/$s_!q_yH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png 1272w, https://substackcdn.com/image/fetch/$s_!q_yH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f2b003d-5a8f-4bdc-99ae-7a798124fd67_778x616.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><br></p></li><li><p>Drag it into the workspace.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FPl8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FPl8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png 424w, https://substackcdn.com/image/fetch/$s_!FPl8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png 848w, https://substackcdn.com/image/fetch/$s_!FPl8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png 1272w, https://substackcdn.com/image/fetch/$s_!FPl8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FPl8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png" width="1456" height="620" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:620,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:167330,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/158909717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FPl8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png 424w, https://substackcdn.com/image/fetch/$s_!FPl8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png 848w, https://substackcdn.com/image/fetch/$s_!FPl8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png 1272w, https://substackcdn.com/image/fetch/$s_!FPl8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ea081-ebf3-43a9-969a-bed7c4c36323_2992x1274.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p></li><li><p>Click the <strong>Edit (pencil) button</strong> on the chart element to open the settings window.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2YM4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2YM4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png 424w, https://substackcdn.com/image/fetch/$s_!2YM4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png 848w, https://substackcdn.com/image/fetch/$s_!2YM4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png 1272w, https://substackcdn.com/image/fetch/$s_!2YM4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2YM4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png" width="1456" height="620" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:620,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:179389,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/158909717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2YM4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png 424w, https://substackcdn.com/image/fetch/$s_!2YM4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png 848w, https://substackcdn.com/image/fetch/$s_!2YM4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png 1272w, https://substackcdn.com/image/fetch/$s_!2YM4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd3721e8-4a83-447b-a703-263456184eaa_2992x1274.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p></li></ol><h3><strong>Step 4: Configuring Chart Settings</strong></h3><p>Follow these settings for a consistent test setup.</p><h4><strong>Basic Information Section</strong></h4><ol><li><p><strong>Title:</strong> "Member Growth 2024"</p></li><li><p><strong>Icon:</strong> Select a chart icon. </p></li><li><p><strong>Chart Type:</strong> Select <strong>Line Chart</strong>. </p></li><li><p><strong>Chart X Axis:</strong> Select <strong>Monthly</strong> to group data by months. </p></li><li><p><strong>Min X Axis &amp; Max X Axis:</strong> Set range from <strong>1 (January) to 12 (December)</strong>. </p></li><li><p><strong>Year:</strong> Set to <strong>2024</strong>. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WsLX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WsLX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png 424w, https://substackcdn.com/image/fetch/$s_!WsLX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png 848w, https://substackcdn.com/image/fetch/$s_!WsLX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png 1272w, https://substackcdn.com/image/fetch/$s_!WsLX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WsLX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png" width="1356" height="1268" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1268,&quot;width&quot;:1356,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:138437,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/158909717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WsLX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png 424w, https://substackcdn.com/image/fetch/$s_!WsLX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png 848w, https://substackcdn.com/image/fetch/$s_!WsLX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png 1272w, https://substackcdn.com/image/fetch/$s_!WsLX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3fc0311-bf7c-4333-a7fd-99fbb47ff17f_1356x1268.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li></ol><h3><strong>Step 5: Configuring the Dataset</strong></h3><ol><li><p><strong>Dataset Title:</strong> "Member Growth"</p></li><li><p><strong>Data Query:</strong> Select the data source using <strong>Query Builder</strong>.</p><ul><li><p>Click <strong>"+"</strong> to create a new query.</p></li><li><p>Name: "Query Chart Member 2024"</p></li><li><p><strong>Builder Mode:</strong> Select <strong>Raw Query</strong>.</p></li><li><p><strong>Raw Query:</strong></p></li></ul></li></ol><pre><code><code>SELECT COUNT(id) AS total, MONTH(created_at) AS month, YEAR(created_at) AS year 
FROM members 
WHERE YEAR(created_at) = 2024
GROUP BY month, year
</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DFZY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DFZY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png 424w, https://substackcdn.com/image/fetch/$s_!DFZY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png 848w, https://substackcdn.com/image/fetch/$s_!DFZY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png 1272w, https://substackcdn.com/image/fetch/$s_!DFZY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DFZY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png" width="1456" height="683" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:683,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:170981,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/158909717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DFZY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png 424w, https://substackcdn.com/image/fetch/$s_!DFZY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png 848w, https://substackcdn.com/image/fetch/$s_!DFZY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png 1272w, https://substackcdn.com/image/fetch/$s_!DFZY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e910c4-0008-4f4c-821a-5416b5966e96_2510x1178.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>Click <strong>"Test Query"</strong> to verify output.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VQNu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VQNu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png 424w, https://substackcdn.com/image/fetch/$s_!VQNu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png 848w, https://substackcdn.com/image/fetch/$s_!VQNu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png 1272w, https://substackcdn.com/image/fetch/$s_!VQNu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VQNu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png" width="1456" height="729" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:729,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:129637,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/158909717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VQNu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png 424w, https://substackcdn.com/image/fetch/$s_!VQNu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png 848w, https://substackcdn.com/image/fetch/$s_!VQNu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png 1272w, https://substackcdn.com/image/fetch/$s_!VQNu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef9a933-2314-45c2-85cb-3c4465662e39_2982x1494.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li><li><p>Click <strong>"Save"</strong> to store the query.</p><p></p></li></ul><ol start="3"><li><p>Return to the <strong>Page Builder tab</strong>, refresh the <strong>Data Query</strong>, and select the query created earlier. </p></li><li><p><strong>Comparator Field:</strong> Enter <strong>"month"</strong> (used to group data on the X-axis).</p></li><li><p><strong>Year Field:</strong> Enter <strong>"year"</strong> (used for filtering year-based data).</p></li><li><p><strong>Point Field:</strong> Enter <strong>"total"</strong> (the count of new members per month).</p></li><li><p>Background, border, and stack settings can be adjusted as needed.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8kv_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8kv_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png 424w, https://substackcdn.com/image/fetch/$s_!8kv_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png 848w, https://substackcdn.com/image/fetch/$s_!8kv_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png 1272w, https://substackcdn.com/image/fetch/$s_!8kv_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8kv_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png" width="1356" height="1268" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1268,&quot;width&quot;:1356,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:128434,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/158909717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8kv_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png 424w, https://substackcdn.com/image/fetch/$s_!8kv_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png 848w, https://substackcdn.com/image/fetch/$s_!8kv_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png 1272w, https://substackcdn.com/image/fetch/$s_!8kv_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda3448d-ae09-4bc6-8cd4-ecb767d08411_1356x1268.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If you need multiple datasets, click <strong>"Add Dataset"</strong> to include more data series in the chart.</p><p>Click <strong>"Save"</strong>, and your chart element will be successfully stored.</p><h3><strong>Step 6: Previewing the Chart</strong></h3><p>Click <strong>"Preview"</strong> to open a new page displaying the chart you created.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sqB2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sqB2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png 424w, https://substackcdn.com/image/fetch/$s_!sqB2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png 848w, https://substackcdn.com/image/fetch/$s_!sqB2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png 1272w, https://substackcdn.com/image/fetch/$s_!sqB2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sqB2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png" width="1456" height="731" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:731,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:203680,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://crudbooster.substack.com/i/158909717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sqB2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png 424w, https://substackcdn.com/image/fetch/$s_!sqB2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png 848w, https://substackcdn.com/image/fetch/$s_!sqB2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png 1272w, https://substackcdn.com/image/fetch/$s_!sqB2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5049b28e-2414-4c45-9516-63b7b3ec7458_2954x1484.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><blockquote><p>Page Builder automatically generates a unique URL for previewing the page.</p></blockquote><h3><strong>Conclusion</strong></h3><p>With CRUDBooster&#8217;s <strong>Page Builder</strong>, creating interactive charts is effortless. You can visualize data dynamically, making your admin panel more insightful.</p><p>&#128640; <strong>Next Steps:</strong></p><ul><li><p>Try different <strong>chart types</strong> (bar, pie, area).</p></li><li><p>Customize the <strong>color scheme</strong> and <strong>labels</strong>.</p></li><li><p>Integrate <strong>real-time data updates</strong>.</p></li></ul><p>Start building your own analytics dashboard today! &#127881; Download <strong><a href="https://crudbooster.com">CRUDBooster Now!</a></strong></p>]]></content:encoded></item><item><title><![CDATA[🚀 Coming Soon: Powerful API Builder by CRUDBooster]]></title><description><![CDATA[Building APIs should be easy, fast, and hassle-free.]]></description><link>https://crudbooster.substack.com/p/coming-soon-powerful-api-builder</link><guid isPermaLink="false">https://crudbooster.substack.com/p/coming-soon-powerful-api-builder</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Mon, 17 Feb 2025 01:16:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!NPg2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NPg2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NPg2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png 424w, https://substackcdn.com/image/fetch/$s_!NPg2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png 848w, https://substackcdn.com/image/fetch/$s_!NPg2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png 1272w, https://substackcdn.com/image/fetch/$s_!NPg2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NPg2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png" width="1246" height="699" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:699,&quot;width&quot;:1246,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:94087,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NPg2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png 424w, https://substackcdn.com/image/fetch/$s_!NPg2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png 848w, https://substackcdn.com/image/fetch/$s_!NPg2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png 1272w, https://substackcdn.com/image/fetch/$s_!NPg2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb050f5e-3ca1-4574-ab63-bfe7304f82ed_1246x699.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Building APIs should be easy, fast, and hassle-free. That's why we're introducing the <strong>Powerful API Builder</strong>, a game-changing feature coming soon to CRUDBooster! Whether you're a solo developer or working on enterprise-grade applications, this new tool will supercharge your workflow.</p><h2>&#128293; What Makes It So Powerful?</h2><h3>&#9989; Easy API Builder &#8211; Just Click and Click</h3><p>No more manually coding repetitive API endpoints. With our <strong>intuitive UI</strong>, you can build APIs with just a few clicks&#8212;effortless, smooth, and developer-friendly.</p><h3>&#9889; Pipeline-Driven</h3><p>Our <strong>pipeline-driven approach</strong> allows you to define API processes step by step. From data transformation to authentication handling, every action is structured for maximum flexibility and control.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i8W1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8727c54a-a087-48c9-bab3-60b4313a552b_1246x783.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i8W1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8727c54a-a087-48c9-bab3-60b4313a552b_1246x783.png 424w, https://substackcdn.com/image/fetch/$s_!i8W1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8727c54a-a087-48c9-bab3-60b4313a552b_1246x783.png 848w, https://substackcdn.com/image/fetch/$s_!i8W1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8727c54a-a087-48c9-bab3-60b4313a552b_1246x783.png 1272w, https://substackcdn.com/image/fetch/$s_!i8W1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8727c54a-a087-48c9-bab3-60b4313a552b_1246x783.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i8W1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8727c54a-a087-48c9-bab3-60b4313a552b_1246x783.png" width="1246" height="783" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8727c54a-a087-48c9-bab3-60b4313a552b_1246x783.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:783,&quot;width&quot;:1246,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:110863,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!i8W1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8727c54a-a087-48c9-bab3-60b4313a552b_1246x783.png 424w, https://substackcdn.com/image/fetch/$s_!i8W1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8727c54a-a087-48c9-bab3-60b4313a552b_1246x783.png 848w, https://substackcdn.com/image/fetch/$s_!i8W1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8727c54a-a087-48c9-bab3-60b4313a552b_1246x783.png 1272w, https://substackcdn.com/image/fetch/$s_!i8W1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8727c54a-a087-48c9-bab3-60b4313a552b_1246x783.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PQj3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca4bd6c-bc35-4315-b3f4-f73b004d09fe_1157x1827.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PQj3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca4bd6c-bc35-4315-b3f4-f73b004d09fe_1157x1827.png 424w, https://substackcdn.com/image/fetch/$s_!PQj3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca4bd6c-bc35-4315-b3f4-f73b004d09fe_1157x1827.png 848w, https://substackcdn.com/image/fetch/$s_!PQj3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca4bd6c-bc35-4315-b3f4-f73b004d09fe_1157x1827.png 1272w, https://substackcdn.com/image/fetch/$s_!PQj3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca4bd6c-bc35-4315-b3f4-f73b004d09fe_1157x1827.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PQj3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca4bd6c-bc35-4315-b3f4-f73b004d09fe_1157x1827.png" width="1157" height="1827" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2ca4bd6c-bc35-4315-b3f4-f73b004d09fe_1157x1827.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1827,&quot;width&quot;:1157,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:208446,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!PQj3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca4bd6c-bc35-4315-b3f4-f73b004d09fe_1157x1827.png 424w, https://substackcdn.com/image/fetch/$s_!PQj3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca4bd6c-bc35-4315-b3f4-f73b004d09fe_1157x1827.png 848w, https://substackcdn.com/image/fetch/$s_!PQj3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca4bd6c-bc35-4315-b3f4-f73b004d09fe_1157x1827.png 1272w, https://substackcdn.com/image/fetch/$s_!PQj3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca4bd6c-bc35-4315-b3f4-f73b004d09fe_1157x1827.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>&#128196; Auto-Generated Documentation</h3><p>Forget about writing API docs manually. Our API Builder <strong>automatically generates documentation</strong> so your team (or future self) always has clear and up-to-date API references.</p><h3>&#127881; FREE for Premium Members!!</h3><p>If you're a <strong>Premium CRUDBooster member</strong>, you get <strong>full access to the API Builder at no extra cost</strong>. Just another reason to upgrade and take your development to the next level!</p><h2>&#128284; Stay Tuned!</h2><p>We&#8217;re in the final stages of development, and we can't wait for you to try it. Keep an eye out for the official release!</p><p>&#128161; Want to be the first to experience it? <strong>Join our Premium plan today</strong> and get early access.</p><p>Start build your admin panel with no code now at <a href="http://crudbooster.com">crudbooster.com</a></p><p>#CRUDBooster #APIBuilder #NoCodeAPI #DevTools #WebDevelopment</p>]]></content:encoded></item><item><title><![CDATA[🚀 CRUDBooster v7.0.27 Update – Bug Fixes & Installation Guide!]]></title><description><![CDATA[Hey CRUDBooster Devs!]]></description><link>https://crudbooster.substack.com/p/crudbooster-v7027-update-bug-fixes</link><guid isPermaLink="false">https://crudbooster.substack.com/p/crudbooster-v7027-update-bug-fixes</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Fri, 14 Feb 2025 16:28:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee0c6c09-25a4-46a0-9b73-f4f6b17a0c2a_1080x1080.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey CRUDBooster Devs!</p><p>We&#8217;ve just rolled out <strong>CRUDBooster v7.0.27</strong>, bringing essential bug fixes to enhance your experience:</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>&#9989; <strong>Fixed installation stuck on Windows</strong> <br>&#9989; <strong>Resolved </strong><code>$slot</code><strong> error on the dashboard</strong></p><p>If you&#8217;ve faced any of these issues, make sure to update to the latest version.</p><p>&#128161; <strong>Need help with installation?</strong><br>I&#8217;ve recently put together a step-by-step installation guide to help you get CRUDBooster up and running smoothly. Watch it here:<br>&#128073; <strong><a href="https://www.youtube.com/watch?v=LpgmR9NtgYs">How to Install CRUDBooster v7</a></strong></p><p>&#128214; <strong>Read the Documentation</strong><br>For a complete guide on using CRUDBooster, check out the official docs:<br>&#128073; <strong><a href="https://crudbooster.com/docs">CRUDBooster Documentation</a><br></strong>&#128073; <strong><a href="https://crudbooster.com/docs#/?id=v7x">Update Guide</a></strong></p><p>As always, your feedback is invaluable! Let us know if you run into any issues submit on <a href="https://github.com/crudbooster/crudbooster-issue-tracker/issues">CB Issue Tracker Here</a></p><p>Happy coding!<br>&#8212; CRUDBooster &#128640;</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[🚀 CRUDBooster is Officially LIVE – AI-Powered CRUD Generator is Here!]]></title><description><![CDATA[Hey developers, CRUDBooster is officially LIVE! &#127881; this is the real deal with powerful new features to speed up your Laravel development.]]></description><link>https://crudbooster.substack.com/p/crudbooster-is-officially-live-ai</link><guid isPermaLink="false">https://crudbooster.substack.com/p/crudbooster-is-officially-live-ai</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Sat, 08 Feb 2025 07:05:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!G30t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!G30t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!G30t!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png 424w, https://substackcdn.com/image/fetch/$s_!G30t!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png 848w, https://substackcdn.com/image/fetch/$s_!G30t!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png 1272w, https://substackcdn.com/image/fetch/$s_!G30t!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!G30t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png" width="1456" height="671" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:671,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:979848,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!G30t!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png 424w, https://substackcdn.com/image/fetch/$s_!G30t!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png 848w, https://substackcdn.com/image/fetch/$s_!G30t!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png 1272w, https://substackcdn.com/image/fetch/$s_!G30t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cbadb50-719a-4c62-b0d7-140ef23cd1cf_2878x1326.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Hey developers, <strong>CRUDBooster is officially LIVE!</strong> &#127881; this is the <strong>real deal</strong> with <strong>powerful new features</strong> to speed up your Laravel development.</p><p>We&#8217;ve taken CRUD automation to the <strong>next level</strong> with <strong>AI-powered generation</strong>, a <strong>smooth SPA-like experience</strong>, and a <strong>drag &amp; drop Page Builder</strong>.</p><h3><strong>What&#8217;s New in the Live Version?</strong></h3><p>&#128293; <strong>1. New CRUD Generator (With AI Support)</strong><br>&#128161; Just type a prompt, and AI will generate the entire CRUD module!<br>&#128161; Advanced CRUD Generator User Interface</p><p>&#128293; <strong>2. Page Builder (Drag &amp; Drop)</strong><br>&#128161; No coding needed&#8212;design custom admin pages in seconds!</p><p>&#128293; <strong>3. Easy Code, Fast Code</strong><br>&#128161; Simple, optimized syntax so you can <strong>build faster than ever!</strong></p><p>&#128293; <strong>4. Better Performance (Smooth SPA-like Experience)</strong><br>&#128161; CRUDBooster feels <strong>snappy &amp; seamless</strong>, just like a modern web app.</p><p>&#128293; <strong>5. RBAC Built-in (Role-Based Access Control)</strong><br>&#128161; <strong>Secure user access</strong> with a built-in role management system!</p><h3><strong>Free for Students &amp; Non-Profit Projects</strong></h3><p>&#128161; <strong>Are you a student or working on a non-profit project?</strong><br>&#9989; <strong>You can use CRUDBooster for FREE!</strong><br>&#9989; We want to support education &amp; meaningful projects.</p><p>&#128176; Building a commercial project? Go <strong>PREMIUM</strong>!<br>&#9989; More AI credits for automation<br>&#9989; Priority support for your projects<br>&#9989; No Contract! No Subscription!</p><p>CRUDBooster is now <strong>production-ready</strong> and <strong>fully optimized</strong> for your Laravel applications.</p><h3><strong>Get Started Today</strong></h3><p>&#128722; Available now! Check out the <strong>demo</strong> here: <a href="https://www.crudbooster.com?channel=substack">www.crudbooster.com</a><br><strong>&#9889; Upgrade your Laravel Project today!</strong></p><p>&#128172; Have questions? We&#8217;re here to help! Drop your thoughts in the comments or reach out to us anytime.</p><p>Let&#8217;s build <strong>faster, smarter, and better</strong> with CRUDBooster! &#128640;</p>]]></content:encoded></item><item><title><![CDATA[ 🚀 Join the CRUDBooster Beta Program!]]></title><description><![CDATA[Are you ready to experience the future of CRUD development?]]></description><link>https://crudbooster.substack.com/p/join-the-crudbooster-beta-program</link><guid isPermaLink="false">https://crudbooster.substack.com/p/join-the-crudbooster-beta-program</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Sun, 26 Jan 2025 03:20:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee0c6c09-25a4-46a0-9b73-f4f6b17a0c2a_1080x1080.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sNiw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffca81377-493c-41f9-93c0-bbc9882eda1e_1015x259.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sNiw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffca81377-493c-41f9-93c0-bbc9882eda1e_1015x259.png 424w, https://substackcdn.com/image/fetch/$s_!sNiw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffca81377-493c-41f9-93c0-bbc9882eda1e_1015x259.png 848w, https://substackcdn.com/image/fetch/$s_!sNiw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffca81377-493c-41f9-93c0-bbc9882eda1e_1015x259.png 1272w, https://substackcdn.com/image/fetch/$s_!sNiw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffca81377-493c-41f9-93c0-bbc9882eda1e_1015x259.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sNiw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffca81377-493c-41f9-93c0-bbc9882eda1e_1015x259.png" width="1015" height="259" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fca81377-493c-41f9-93c0-bbc9882eda1e_1015x259.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:259,&quot;width&quot;:1015,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:42198,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sNiw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffca81377-493c-41f9-93c0-bbc9882eda1e_1015x259.png 424w, https://substackcdn.com/image/fetch/$s_!sNiw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffca81377-493c-41f9-93c0-bbc9882eda1e_1015x259.png 848w, https://substackcdn.com/image/fetch/$s_!sNiw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffca81377-493c-41f9-93c0-bbc9882eda1e_1015x259.png 1272w, https://substackcdn.com/image/fetch/$s_!sNiw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffca81377-493c-41f9-93c0-bbc9882eda1e_1015x259.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Are you ready to experience the future of CRUD development? CRUDBooster is evolving, and we're excited to invite you to join our exclusive Beta Program! This is your chance to get early access to new features, cutting-edge AI-powered tools, and a more powerful development experience&#8212;all while helping us shape the future of CRUDBooster.</p><p><strong>&#129513; What&#8217;s New in the Beta Version?</strong></p><p><strong>Enhanced AI Module Generator:</strong> Generate modules and dummy data in seconds.</p><p><strong>Customizable</strong> <strong>Input Types</strong>: Easily extend and integrate with packages or your custom input types.</p><p><strong>Page Builder:</strong> Build dashboards and pages faster than ever before.</p><p><strong>Streamlined Performance</strong>: Optimized speed and functionality for better development flow.</p><p><strong>&#128221; What You Need to Know</strong></p><p>The beta version is not for production use; it&#8217;s for testing purposes only.</p><p>You may encounter some <strong>bugs, incomplete features, or areas that need improvement.</strong> Your feedback will help us address these issues before the official release.</p><p><strong>Limited Slots:</strong> Not all submissions will be approved due to limited capacity. If you don&#8217;t receive an email from us, don&#8217;t worry&#8212;your interest is still greatly appreciated, and you&#8217;ll be notified of future opportunities.</p><p><strong>Beta Period:</strong> This program is available only until <strong>February 10, 2025,</strong> so make sure to apply before the deadline!</p><p><strong>&#127775; Why Join?</strong></p><p>Be the first to explore our latest tools and features.</p><p>Influence the development of CRUDBooster with your feedback.</p><p>Gain insider access to upcoming updates.</p><p><strong>&#128682; How to Join</strong></p><p>Joining is simple! Click the link below and submit your application:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://bit.ly/join-crudbooster-beta&quot;,&quot;text&quot;:&quot;Join the CRUDBooster Beta Program&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://bit.ly/join-crudbooster-beta"><span>Join the CRUDBooster Beta Program</span></a></p><p><em>*Note: If you don&#8217;t receive a confirmation email, don&#8217;t be discouraged. We&#8217;re keeping the beta exclusive, and there may be more opportunities in the future.</em></p>]]></content:encoded></item><item><title><![CDATA[POV Developer: Building Dashboards Without Coding, Just Drag & Drop! ]]></title><description><![CDATA[Have you ever dreamed of creating a fully functional dashboard without writing a single line of code? Imagine the power of simply dragging and dropping elements like charts, tables, maps, images, and]]></description><link>https://crudbooster.substack.com/p/pov-developer-building-dashboards</link><guid isPermaLink="false">https://crudbooster.substack.com/p/pov-developer-building-dashboards</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Thu, 19 Dec 2024 04:19:33 GMT</pubDate><enclosure url="https://api.substack.com/feed/podcast/153344944/0e771ed6c58ec25a7e2776714d5b91ac.mp3" length="0" type="audio/mpeg"/><content:encoded><![CDATA[<p>Well, with the upcoming release of CRUDBooster, this dream is becoming a reality.</p><h3>Introducing the Page Builder by CRUDBooster</h3><p>The next version of CRUDBooster will feature an intuitive <strong>Page Builder</strong>. Whether you need to craft a professional report, an interactive admin panel, or a custom dashboard, the process will be as simple as selecting elements, arranging layouts, and clicking "save." Here&#8217;s what you can expect:</p><ul><li><p><strong>Flexible Layouts:</strong> Choose from various column styles to create the structure you need.</p></li><li><p><strong>Dynamic Elements:</strong> Add data tables, counters, charts, maps, headings, paragraphs, and images effortlessly.</p></li><li><p><strong>Versatile Usage:</strong> Set your customized dashboard as a default homepage, a detailed report page, or anything else you envision.</p></li></ul><p>It&#8217;s the ultimate tool for developers who want to save time and focus on what really matters. Whether you&#8217;re working on a client&#8217;s project or just need to visualize data quickly, CRUDBooster&#8217;s Page Builder saves you time and effort while delivering impressive results. </p><p>But here&#8217;s the kicker: <strong>it&#8217;ll include both free and premium options.</strong></p><h3>Watch the Demo</h3><p>I recently shared a sneak peek on TikTok, showcasing how easy it is to build a dashboard with CRUDBooster. Check out how the Page Builder works:  <a href="https://www.tiktok.com/@bapakngoding/video/7449056854853881096">here</a>.</p><h3>Coming Soon</h3><p>We&#8217;re in the final stages of development, and we can&#8217;t wait to share it with you. Follow us on Substack and TikTok (<a href="http://tiktok.com/@bapakngoding">@bapakngoding</a>) for more sneak peeks and updates. Trust us, you won&#8217;t want to miss this release.</p><p>Let&#8217;s build faster, smarter, and with less effort. CRUDBooster is here to transform how you create CRUD applications and beyond.</p><p>Stay tuned! &#128640;</p>]]></content:encoded></item><item><title><![CDATA[What If You Could Generate Modules with AI? We're Making It Happen!]]></title><description><![CDATA[The Perfect Blend of AI and CRUD Booster for Faster Development]]></description><link>https://crudbooster.substack.com/p/what-if-you-could-generate-modules</link><guid isPermaLink="false">https://crudbooster.substack.com/p/what-if-you-could-generate-modules</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Fri, 13 Dec 2024 08:05:35 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Bs-c!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Bs-c!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Bs-c!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png 424w, https://substackcdn.com/image/fetch/$s_!Bs-c!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png 848w, https://substackcdn.com/image/fetch/$s_!Bs-c!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!Bs-c!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Bs-c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png" width="1456" height="811" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:811,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:920061,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Bs-c!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png 424w, https://substackcdn.com/image/fetch/$s_!Bs-c!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png 848w, https://substackcdn.com/image/fetch/$s_!Bs-c!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!Bs-c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09c1a42-42d6-4809-8aff-66574f5c5070_2872x1600.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Imagine this: you're sipping your coffee, and instead of spending hours coding, you simply tell an AI what you need&#8212;a module for your project&#8212;and in minutes, it's ready for you. Sounds futuristic? Well, we&#8217;re bringing that future closer to reality.</p><p><strong>For developers</strong>, generating modules with tools like CRUD Booster has already been a time-saver. Just by clicking through its intuitive interface, you can create powerful modules in no time. Now, imagine combining that efficiency with AI! Not only does CRUD Booster help you quickly set up modules, but with AI assisting in the initial setup&#8212;defining entities, columns, and relationships&#8212;you&#8217;ll get things done even faster.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>The Vision</strong></h2><p>We&#8217;re in the process of building an AI-powered tool that integrates seamlessly with CRUD Booster to take module generation to the next level. Think of it as your personal coding assistant, trained to understand your needs and deliver clean, efficient code that integrates seamlessly into your projects.</p><h2><strong>How It Works (Soon!)</strong></h2><p>While the tool is still under development, the idea is simple:</p><p><strong>Input Your Requirements:</strong> Describe what you need in plain language or a pre-defined format.</p><p><strong>AI Does the Heavy Lifting:</strong> Our AI analyzes your input and generates the module code.</p><p><strong>Review and Tweak:</strong> You get a fully functional module, with the ability to tweak and refine it further.</p><h2><strong>Why This Matters</strong></h2><p><strong>Save Time:</strong> Let the AI handle repetitive coding tasks while you focus on innovation.</p><p><strong>Great for Starters:</strong> You don&#8217;t have to worry about defining entities or columns&#8212;our AI will provide smart defaults to get you started.</p><p><strong>Reduce Complexity:</strong> Simplifies the initial setup, making development faster and easier.</p><h2><strong>Where We Are Now</strong></h2><p>Development is in full swing, and while we&#8217;re not ready to launch just yet, we&#8217;re excited to share our progress with you. This tool has the potential to revolutionize how modules are created, and we&#8217;re committed to getting it just right before it reaches your hands.</p><h2><strong>Stay Tuned</strong></h2><p>If this sounds like something you&#8217;d want to use, make sure you&#8217;re subscribed! In early 2025, I&#8217;ll be sharing more updates, behind-the-scenes insights, and even sneak peeks of the tool in action.</p><p>Let&#8217;s shape the future of coding together!</p><p><strong>Start build your admin panel with no code now at <a href="http://crudbooster.com">crudbooster.com</a></strong></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Quick Poll: What's Your Go-To WYSIWYG Editor?]]></title><description><![CDATA[Remember the days of wrestling with HTML forms just to create rich text content? Yeah, me too. That's why WYSIWYG editors are a game-changer.]]></description><link>https://crudbooster.substack.com/p/quick-poll-whats-your-go-to-wysiwyg</link><guid isPermaLink="false">https://crudbooster.substack.com/p/quick-poll-whats-your-go-to-wysiwyg</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Thu, 21 Nov 2024 04:25:36 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ZhpX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZhpX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZhpX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png 424w, https://substackcdn.com/image/fetch/$s_!ZhpX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png 848w, https://substackcdn.com/image/fetch/$s_!ZhpX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png 1272w, https://substackcdn.com/image/fetch/$s_!ZhpX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZhpX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png" width="892" height="453" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:453,&quot;width&quot;:892,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;tinymce-wysiwyg-editor-plugin-advanced-full-featured-codexworld - CodexWorld&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="tinymce-wysiwyg-editor-plugin-advanced-full-featured-codexworld - CodexWorld" title="tinymce-wysiwyg-editor-plugin-advanced-full-featured-codexworld - CodexWorld" srcset="https://substackcdn.com/image/fetch/$s_!ZhpX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png 424w, https://substackcdn.com/image/fetch/$s_!ZhpX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png 848w, https://substackcdn.com/image/fetch/$s_!ZhpX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png 1272w, https://substackcdn.com/image/fetch/$s_!ZhpX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98c8008d-1f01-4717-9d0c-4ad9ab007250_892x453.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Let's talk about the elephant in the room: WYSIWYG editors all have their quirks.</p><ul><li><p>TinyMCE: &#10133; Feature-rich, great docs &#10134; Legacy issues, can be heavy, licensing concerns</p></li><li><p>CKEditor: &#10133; Reliable, good community &#10134; Complex configuration, steeper learning curve</p></li><li><p>Summernote: &#10133; Lightweight, easy to implement &#10134; Limited features, Bootstrap dependency</p></li><li><p>Quill: &#10133; Modern, clean API &#10134; Fewer plugins, limited table support</p></li><li><p>Trix (by Basecamp): &#10133; Simple, focused on content-first &#10133; Great for basic formatting &#10134; Limited customization &#10134; No tables or advanced features</p></li></ul><p>As we rebuild CRUDBooster, I'm curious:</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="poll-embed" data-attrs="{&quot;id&quot;:237850}" data-component-name="PollToDOM"></div><p>Share your experiences in the comment below. Which quirks drive you crazy? What features can't you live without?</p><p><strong>Your input will shape newest version of CRUDBooster's WYSIWYG integration.</strong></p><p>P.S. Know a developer with strong WYSIWYG opinions? Share this poll with them!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Exciting Updates: CRUDBooster's Next Version is on the Way!]]></title><description><![CDATA[Hi CRUDBooster Community,]]></description><link>https://crudbooster.substack.com/p/exciting-updates-crudboosters-next</link><guid isPermaLink="false">https://crudbooster.substack.com/p/exciting-updates-crudboosters-next</guid><dc:creator><![CDATA[Ferry Ariawan]]></dc:creator><pubDate>Thu, 17 Oct 2024 01:13:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ISUR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ISUR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ISUR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png 424w, https://substackcdn.com/image/fetch/$s_!ISUR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png 848w, https://substackcdn.com/image/fetch/$s_!ISUR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png 1272w, https://substackcdn.com/image/fetch/$s_!ISUR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ISUR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png" width="1456" height="825" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:825,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1388892,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ISUR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png 424w, https://substackcdn.com/image/fetch/$s_!ISUR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png 848w, https://substackcdn.com/image/fetch/$s_!ISUR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png 1272w, https://substackcdn.com/image/fetch/$s_!ISUR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F138fd473-647c-4496-a5e3-737b2de148eb_2880x1632.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Hi <strong>CRUDBooster</strong> Community,</p><p>First of all, thank you so much for the overwhelming support and enthusiasm you&#8217;ve shown for <strong>CRUDBooster</strong>. Your contributions, feedback, and continuous use of the platform mean the world to me and keep the project moving forward.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>I&#8217;m excited to share that the development of the new <strong>CRUDBooster</strong> version is in full swing! My target is to release the <strong>beta version around January ~ February 2025</strong>. This upcoming version will bring exciting features and improvements, making it easier and more powerful for everyone to use.</p><p>If you have any feedback, suggestions, or features you&#8217;d love to see included, feel free to share them in the comments below! Your input is invaluable in shaping <strong>CRUDBooster's</strong> future.</p><p>For those of you who want to support the development of CRUDBooster, you can now help through donations. If you'd like to contribute, here&#8217;s the link: <strong><a href="https://paypal.me/ferryariawan">https://paypal.me/ferryariawan</a></strong>. Every bit of support helps me dedicate more time and resources to making CRUDBooster the best it can be.</p><p>Thank you once again, and I can't wait to share the new CRUDBooster with all of you soon!</p><p>Best,  </p><p>Ferry Ariwan  </p><p>Founder of CRUDBooster</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://crudbooster.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CRUDBooster's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item></channel></rss>