<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Serg</title>
    <description>The latest articles on DEV Community by Serg (@karakhanyans).</description>
    <link>https://dev.to/karakhanyans</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1336032%2F80134c1b-5f74-495c-ba05-5f91cddcdf84.jpg</url>
      <title>DEV Community: Serg</title>
      <link>https://dev.to/karakhanyans</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/karakhanyans"/>
    <language>en</language>
    <item>
      <title>Larafast Multi-Tenancy is Live — Here's Why I Built It</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Tue, 28 Oct 2025 07:56:06 +0000</pubDate>
      <link>https://dev.to/karakhanyans/larafast-multi-tenancy-is-live-heres-why-i-built-it-3dc5</link>
      <guid>https://dev.to/karakhanyans/larafast-multi-tenancy-is-live-heres-why-i-built-it-3dc5</guid>
      <description>&lt;p&gt;When I started building SaaS projects in Laravel, I hit the same wall every time.&lt;/p&gt;

&lt;p&gt;Tenant management. Domain routing. Billing setup. Admin dashboards.&lt;/p&gt;

&lt;p&gt;Each new app meant weeks of setup before writing a single line of code that actually mattered.&lt;/p&gt;

&lt;p&gt;That’s when &lt;strong&gt;Larafast Multitenancy&lt;/strong&gt; was born — a Laravel 12 + Filament 4 starter kit that helps you &lt;strong&gt;launch a multi-tenant SaaS in days&lt;/strong&gt; instead of months.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ The Problem Every Laravel Developer Faces
&lt;/h2&gt;

&lt;p&gt;If you’ve ever built a SaaS with multi-tenancy, you know how messy it gets.&lt;/p&gt;

&lt;p&gt;You handle tenant isolation, subdomains, custom domains, and user roles.&lt;br&gt;
Then you add billing, authentication, and email systems.&lt;br&gt;
And suddenly you’ve spent three weeks just building &lt;strong&gt;infrastructure&lt;/strong&gt;, not your product.&lt;/p&gt;

&lt;p&gt;I wanted to stop wasting that time. I wanted something clean, production-ready, and easy to extend.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 The Turning Point
&lt;/h2&gt;

&lt;p&gt;A year ago, I was building a small SaaS idea. It was supposed to take a weekend.&lt;br&gt;
It took three weeks — because of tenancy logic, domain setup, and user management.&lt;/p&gt;

&lt;p&gt;That moment changed everything.&lt;br&gt;
I decided to build a starter kit that saves developers from that grind.&lt;br&gt;
So I rewrote everything from scratch — clean code, tested architecture, and modern stack.&lt;/p&gt;

&lt;p&gt;That became &lt;strong&gt;Larafast Multitenancy&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ What’s Inside
&lt;/h2&gt;

&lt;p&gt;Here’s what comes built-in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tenant isolation (single or multi-database)&lt;/li&gt;
&lt;li&gt;Domain and subdomain routing&lt;/li&gt;
&lt;li&gt;Filament 4 admin dashboard&lt;/li&gt;
&lt;li&gt;Stripe, Paddle, and LemonSqueezy billing&lt;/li&gt;
&lt;li&gt;Custom branding for each tenant&lt;/li&gt;
&lt;li&gt;Authentication with 2FA, email verification, and social login&lt;/li&gt;
&lt;li&gt;SEO-friendly URLs and meta setup&lt;/li&gt;
&lt;li&gt;REST API ready with Laravel Sanctum&lt;/li&gt;
&lt;li&gt;Fully tested and ready for production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All built with &lt;strong&gt;Laravel 12&lt;/strong&gt;, &lt;strong&gt;Livewire&lt;/strong&gt;, and &lt;strong&gt;Tailwind 4&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Real Example — Directify Runs on It
&lt;/h2&gt;

&lt;p&gt;I didn’t want to release theory.&lt;br&gt;
So I used it myself — on &lt;a href="https://directify.app" rel="noopener noreferrer"&gt;&lt;strong&gt;Directify&lt;/strong&gt;&lt;/a&gt;, my no-code directory website builder.&lt;/p&gt;

&lt;p&gt;Directify runs entirely on Larafast Multitenancy.&lt;br&gt;
Every user gets an isolated tenant, their own domain, and a separate environment.&lt;br&gt;
No hacks. No duplicated code. Just clean multitenancy built right.&lt;/p&gt;

&lt;p&gt;That was the moment I knew this kit worked.&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 Final Words
&lt;/h2&gt;

&lt;p&gt;If you’re tired of building tenancy logic from scratch every time, this kit will save you weeks.&lt;/p&gt;

&lt;p&gt;I built it so you can focus on the parts users actually see — and ship faster.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://larafast.com/multitenancy" rel="noopener noreferrer"&gt;Get Larafast Multitenancy ($299 Launch Price)&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Lifetime updates. No recurring fees. Premium support included.&lt;/p&gt;




&lt;h3&gt;
  
  
  📘 Built With
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://laravel.com/docs" rel="noopener noreferrer"&gt;Laravel 12 Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://filamentphp.com/docs" rel="noopener noreferrer"&gt;Filament 4 Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stripe.com/docs" rel="noopener noreferrer"&gt;Stripe Developer Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.paddle.com" rel="noopener noreferrer"&gt;Paddle Developer Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.lemonsqueezy.com" rel="noopener noreferrer"&gt;LemonSqueezy Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🧠 More From Me
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://larafast.com/blog/why-choose-larafast-as-a-saas-starter-kit-in-2024" rel="noopener noreferrer"&gt;Why Choose Larafast as a SaaS Starter Kit in 2025?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://larafast.com/blog/7-best-laravel-starter-kits-for-2024" rel="noopener noreferrer"&gt;7 Best Laravel Starter Kits for 2025&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Follow me on &lt;a href="https://x.com/karakhanyans" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or check out &lt;a href="https://larafast.com" rel="noopener noreferrer"&gt;Larafast&lt;/a&gt; if you want to build faster with Laravel.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>filament</category>
    </item>
    <item>
      <title>How to Create an Online Directory</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Thu, 27 Feb 2025 10:38:53 +0000</pubDate>
      <link>https://dev.to/karakhanyans/how-to-create-an-online-directory-3kd7</link>
      <guid>https://dev.to/karakhanyans/how-to-create-an-online-directory-3kd7</guid>
      <description>&lt;p&gt;Creating an online directory has never been easier, thanks to no-code platforms like &lt;a href="https://directify.app" rel="noopener noreferrer"&gt;Directify&lt;/a&gt;. Whether you're looking to list local businesses, community resources, or specialized services, Directify offers a streamlined solution to build and manage your directory website without any coding expertise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Choose Directify for Your Online Directory?
&lt;/h2&gt;

&lt;p&gt;Directify is designed to simplify the process of creating professional directory websites. With its user-friendly interface and robust features, you can have your directory up and running in no time. &lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features of Directify
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No Coding Required:&lt;/strong&gt; Build and customize your directory without any technical skills.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable Themes:&lt;/strong&gt; Choose from a variety of themes to design a unique look and feel for your directory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO Optimization:&lt;/strong&gt; Built-in SEO tools, including sitemaps and rich snippets, help improve your site's visibility on search engines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Domains:&lt;/strong&gt; Connect your own domain to enhance your brand identity with a simple DNS setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monetization:&lt;/strong&gt; Easily set up paid listings by connecting payment platforms like Stripe or Lemon Squeezy, allowing you to accept payments directly from your directory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team Collaboration:&lt;/strong&gt; Invite team members to collaborate on your directory, with the ability to manage roles and permissions through an intuitive interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Import/Export:&lt;/strong&gt; Import listings, categories, and blog articles from CSV files, and export your data for future use.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read about the steps on how to create directory with Directify here: &lt;a href="https://directify.app/blog/how-to-create-an-online-directory/" rel="noopener noreferrer"&gt;https://directify.app/blog/how-to-create-an-online-directory/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nocode</category>
      <category>directories</category>
      <category>webdev</category>
    </item>
    <item>
      <title>7 Steps to Launch Your First Online Directory Website</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Thu, 12 Dec 2024 19:45:15 +0000</pubDate>
      <link>https://dev.to/karakhanyans/7-steps-to-launch-your-first-online-directory-website-2bej</link>
      <guid>https://dev.to/karakhanyans/7-steps-to-launch-your-first-online-directory-website-2bej</guid>
      <description>&lt;p&gt;Creating an online directory is easier than ever with no-code tools. Here’s how to get started:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Choose a Niche&lt;/strong&gt;: Focus on a specific market with demand, like local yoga studios or eco-friendly services. Research keywords and competitors to find gaps you can fill.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pick a No-Code Platform&lt;/strong&gt;: Use tools like &lt;a href="https://directify.app/" rel="noopener noreferrer"&gt;Directify&lt;/a&gt;, &lt;a href="https://www.softr.io/" rel="noopener noreferrer"&gt;Softr&lt;/a&gt;, or &lt;a href="https://bubble.io/" rel="noopener noreferrer"&gt;Bubble&lt;/a&gt; to design your directory without coding. Consider features, pricing, and scalability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Design the Layout&lt;/strong&gt;: Customize your directory’s look, ensure usability with clear categories, and organize listings for easy navigation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Optimize for SEO&lt;/strong&gt;: Use clear URLs, meta titles, and schema markup to rank higher on search engines. Add fresh content regularly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monetize&lt;/strong&gt;: Earn through premium listings, subscription plans, and ad space. Start simple and scale as your directory grows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add Content &amp;amp; Test&lt;/strong&gt;: Populate with at least 50 listings, test on devices, and gather feedback for improvements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Launch &amp;amp; Promote&lt;/strong&gt;: Announce your directory via email and social media. Partner with businesses and leverage Google Ads for visibility.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Quick Comparison of No-Code Platforms
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Starting Price&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;th&gt;Key Features&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://directify.app/" rel="noopener noreferrer"&gt;Directify&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;$24.5/month&lt;/td&gt;
&lt;td&gt;Directory-specific needs&lt;/td&gt;
&lt;td&gt;Unlimited listings, built-in tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Softr&lt;/td&gt;
&lt;td&gt;$25/month&lt;/td&gt;
&lt;td&gt;Beginners&lt;/td&gt;
&lt;td&gt;Simple templates, fast setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bubble&lt;/td&gt;
&lt;td&gt;$25/month&lt;/td&gt;
&lt;td&gt;Advanced customization&lt;/td&gt;
&lt;td&gt;High flexibility, steep learning curve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Webflow&lt;/td&gt;
&lt;td&gt;$12/month&lt;/td&gt;
&lt;td&gt;Design-focused users&lt;/td&gt;
&lt;td&gt;Great for SEO, advanced styling&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Start small, focus on user needs, and improve as you grow. With the right approach, your directory can become a go-to resource for your niche.&lt;/p&gt;

&lt;p&gt;Read full article here &lt;a href="https://directify.app/blog/7-steps-to-launch-your-first-online-directory-website/" rel="noopener noreferrer"&gt;https://directify.app/blog/7-steps-to-launch-your-first-online-directory-website/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nocode</category>
      <category>webdev</category>
      <category>directories</category>
    </item>
    <item>
      <title>My First No-Code SaaS Took off - $8K in 40 days</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Fri, 06 Dec 2024 09:43:59 +0000</pubDate>
      <link>https://dev.to/karakhanyans/my-first-no-code-saas-took-off-8k-in-40-days-2jp8</link>
      <guid>https://dev.to/karakhanyans/my-first-no-code-saas-took-off-8k-in-40-days-2jp8</guid>
      <description>&lt;p&gt;Hey guys. I wanted to share my journey with Directify, a no-code directory website builder I've been working on, and how it's absolutely crushed its first month.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Backstory
&lt;/h2&gt;

&lt;p&gt;Like many of you, I've been grinding on side projects for years. I started to sell Starter Kits by the beginning of the year, and among them I had Directory Starter Kit. One of my customers who bought that, asked me "Do you plan to have Directory as a SaaS one day, to not care about hosting, fully no-code, easy setup, templates, etc". That's when the idea poped out and Directify was born.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Directify?
&lt;/h2&gt;

&lt;p&gt;It's a no-code platform that lets users:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create directory websites in minutes&lt;/li&gt;
&lt;li&gt;Add listings, categories, and search functionality&lt;/li&gt;
&lt;li&gt;Add custom codes, styles, &lt;/li&gt;
&lt;li&gt;Monetize through paid listings and ads&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Revenue: $8199 in first 40 days&lt;/li&gt;
&lt;li&gt;Users: 263&lt;/li&gt;
&lt;li&gt;Directories created: 330&lt;/li&gt;
&lt;li&gt;Listings added: 3647&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Learnings
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Solve a real problem people actually have&lt;/li&gt;
&lt;li&gt;Price competitively (starts at $24.5/month)&lt;/li&gt;
&lt;li&gt;Focus on user experience&lt;/li&gt;
&lt;li&gt;Provide killer customer support&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Initial marketing was tough&lt;/li&gt;
&lt;li&gt;Lots of late nights debugging&lt;/li&gt;
&lt;li&gt;Constant feature improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add more template designs&lt;/li&gt;
&lt;li&gt;Provide more customizations&lt;/li&gt;
&lt;li&gt;Expand marketing channels&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would love to hear your thoughts and experiences with no-code tools! Any questions about &lt;a href="https://directify.app" rel="noopener noreferrer"&gt;Directify&lt;/a&gt;, ask away.&lt;/p&gt;

</description>
      <category>nocode</category>
      <category>filament</category>
      <category>laravel</category>
      <category>webdev</category>
    </item>
    <item>
      <title>10 Laravel Project Ideas For Beginners to Advanced Level in 2024</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Fri, 13 Sep 2024 11:02:55 +0000</pubDate>
      <link>https://dev.to/karakhanyans/10-laravel-project-ideas-for-beginners-to-advanced-level-in-2024-3kpn</link>
      <guid>https://dev.to/karakhanyans/10-laravel-project-ideas-for-beginners-to-advanced-level-in-2024-3kpn</guid>
      <description>&lt;p&gt;Laravel is one of the most popular PHP frameworks, known for its elegant syntax and powerful features. Whether you are just starting out or looking to enhance your skills, building projects is one of the best ways to learn. In this article, we’ll explore 10 Laravel project ideas that range from beginner to advanced levels, helping you take your skills to the next level in 2024.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; If you’re looking for a way to speed up your development process, consider using &lt;a href="https://larafast.com" rel="noopener noreferrer"&gt;Larafast&lt;/a&gt;, a powerful Laravel starter kit that comes pre-configured with essential features, saving you time and effort on the setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beginner Level
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;To-Do List Application&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A simple to-do list application is a classic beginner project. This project will introduce you to the basics of Laravel, including routing, controllers, and views. You’ll learn how to create, read, update, and delete tasks using Eloquent ORM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User authentication&lt;/li&gt;
&lt;li&gt;Task CRUD (Create, Read, Update, Delete)&lt;/li&gt;
&lt;li&gt;Task categorization&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Personal Blog&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Creating a personal blog is a great way to get familiar with Laravel’s features while building something you can actually use. This project will help you understand how to manage content and build a dynamic website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blog post CRUD&lt;/li&gt;
&lt;li&gt;Tagging system&lt;/li&gt;
&lt;li&gt;Comments section&lt;/li&gt;
&lt;li&gt;Simple WYSIWYG editor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Boost Your Development:&lt;/strong&gt; With &lt;a href="https://larafast.com" rel="noopener noreferrer"&gt;Larafast&lt;/a&gt;, you can get your personal blog up and running in no time. It comes with built-in user authentication and a flexible admin panel, so you can focus on customizing your blog rather than starting from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Contact Form with Email Notifications&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A contact form is a small but essential component of many web applications. This project will teach you how to handle form submissions, validate data, and send emails using Laravel’s Mail system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Form validation&lt;/li&gt;
&lt;li&gt;Sending emails using SMTP&lt;/li&gt;
&lt;li&gt;Email templates with Markdown&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Intermediate Level
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Simple E-commerce Store&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Building a simple e-commerce store is an excellent way to dive into more complex Laravel features. This project will introduce you to payment gateways, shopping carts, and product management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product catalog with categories&lt;/li&gt;
&lt;li&gt;Shopping cart functionality&lt;/li&gt;
&lt;li&gt;User authentication and profile management&lt;/li&gt;
&lt;li&gt;Payment gateway integration (e.g., Stripe or PayPal)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Speed Up Your Development:&lt;/strong&gt; &lt;a href="https://larafast.com" rel="noopener noreferrer"&gt;Larafast&lt;/a&gt; can give you a head start on your e-commerce store. With pre-built modules for authentication, user roles, and even basic product management, you can focus on what matters—building a great shopping experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;URL Shortener&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A URL shortener like Bitly is a practical project that combines multiple Laravel features. You'll work with routing, controllers, and database management to create a tool that shortens long URLs into compact, shareable links.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URL shortening and redirection&lt;/li&gt;
&lt;li&gt;Click tracking&lt;/li&gt;
&lt;li&gt;User authentication for link management&lt;/li&gt;
&lt;li&gt;Analytics dashboard&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. &lt;strong&gt;Event Management System&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;An event management system is a more complex project that involves managing events, registrations, and ticketing. This project will help you get comfortable with more advanced database relationships and user roles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event creation and management&lt;/li&gt;
&lt;li&gt;User registration for events&lt;/li&gt;
&lt;li&gt;Ticket generation and email notifications&lt;/li&gt;
&lt;li&gt;Admin panel for event oversight&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Advanced Level
&lt;/h2&gt;

&lt;p&gt;Read more about Advanced Level &lt;a href="https://larafast.com/blog/10-laravel-project-ideas-for-beginners-to-advanced-level-in-2024" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Directory Templates: How to Pick the Best One for Your Project</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Thu, 06 Jun 2024 16:55:16 +0000</pubDate>
      <link>https://dev.to/karakhanyans/directory-templates-how-to-pick-the-best-one-for-your-project-46oa</link>
      <guid>https://dev.to/karakhanyans/directory-templates-how-to-pick-the-best-one-for-your-project-46oa</guid>
      <description>&lt;p&gt;Creating a directory website can be a time consuming task, but using the right directory templates can simplify the process significantly. This guide will help you dig deeper into Larafast Directories Boilerplate, by discussing the key factors to consider and the benefits of using customizable templates.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Check &lt;a href="https://larafast.com/projects/directories" rel="noopener noreferrer"&gt;Larafast Directories&lt;/a&gt; for your next Directory Project&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Directory Templates Matter
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Role of Templates in Directory Websites
&lt;/h3&gt;

&lt;p&gt;Directory templates are designed to provide a directory structure for the future website, with functionality that is required for directory website, which is Categories, Product Listings, Admin Panel to manage everything. Some directories require subscription or one-time payments from users to list their product, so having a pre-built payment system is also a crucial case. &lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of Using Templates
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Time Efficiency:&lt;/strong&gt; Templates save time by providing pre-designed layouts and features, allowing you to focus on content and customization rather than starting from scratch.&lt;br&gt;
&lt;strong&gt;Cost-Effective:&lt;/strong&gt; Using a template can be more cost-effective than hiring a designer to create a custom site from the ground up.&lt;br&gt;
&lt;strong&gt;Consistency:&lt;/strong&gt; Templates ensure a consistent look and feel across your website, which is essential for maintaining a professional appearance.&lt;br&gt;
&lt;strong&gt;Functionality:&lt;/strong&gt; Many templates come with built-in features tailored for directory sites, such as search functionality, listing management, and user review systems.&lt;br&gt;
&lt;strong&gt;Customizability:&lt;/strong&gt; High-quality templates offer customization options that allow you to tailor the site to your specific needs without extensive coding knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Factors to Consider When Choosing a Template
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Customization Options
&lt;/h3&gt;

&lt;p&gt;When selecting a directory template, it's crucial to consider the level of customization it offers. A good template should allow you to adjust colors, fonts, layouts, and other design elements to match your brand identity. Look for templates with flexible customization across design part as well as coding flexibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ease of Use
&lt;/h3&gt;

&lt;p&gt;The ease of use of a template can significantly impact your development process. Choose a template that is user-friendly and comes with comprehensive documentation and support. A well-documented template will save you time and frustration, making it easier to implement and modify according to your needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  SEO Optimization
&lt;/h3&gt;

&lt;p&gt;SEO optimization is vital for any directory website to ensure that your listings appear in search engine results. Select a template that is built with SEO best practices in mind, such as fast loading times, mobile responsiveness, and clean code. Templates that include SEO tools or plugins can further enhance your site's visibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why choose Larafast Directories?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Larafast Directories: Features and Benefits
&lt;/h3&gt;

&lt;p&gt;Larafast Directories is a powerful and flexible directory template designed to help you create professional directory websites with ease. It offers a range of features tailored specifically for directory sites, making it an ideal choice for developers and businesses alike.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product Listing management&lt;/li&gt;
&lt;li&gt;Pre-defined popular Categories&lt;/li&gt;
&lt;li&gt;Search accross categories and products&lt;/li&gt;
&lt;li&gt;SEO optimization for Categories and Products&lt;/li&gt;
&lt;li&gt;Automatic Sitemap generation to index pages on Google fast&lt;/li&gt;
&lt;li&gt;Admin panel to mange categories, products, users, etc.&lt;/li&gt;
&lt;li&gt;User Authentication and Dashboard&lt;/li&gt;
&lt;li&gt;Payment System to manage paid listings&lt;/li&gt;
&lt;li&gt;Blog&lt;/li&gt;
&lt;li&gt;30+ Themes for every taste&lt;/li&gt;
&lt;li&gt;Documentation and Support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enhances user experience with a clean, intuitive interface&lt;/li&gt;
&lt;li&gt;Saves time with pre-built components and layouts&lt;/li&gt;
&lt;li&gt;Boosts SEO efforts with optimized code and structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By selecting a template that meets your specific needs and goals, you can streamline the development process and create a site that not only looks great but also performs well. Make an informed choice and set the foundation for a successful directory project with the right template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://larafast.com/projects/directories" rel="noopener noreferrer"&gt;Get Larafast Directories&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>directories</category>
      <category>php</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Track Unique User Visits and Match with Purchases</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Wed, 08 May 2024 12:55:46 +0000</pubDate>
      <link>https://dev.to/karakhanyans/track-unique-user-visits-and-match-with-purchases-1idj</link>
      <guid>https://dev.to/karakhanyans/track-unique-user-visits-and-match-with-purchases-1idj</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9brywid95u6d6cedh7y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9brywid95u6d6cedh7y.png" alt="Thumb" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's very important to understand from where users visiting the website and which visits turned into purchase from users.&lt;/p&gt;

&lt;p&gt;In this tutorial I will show you how I track users unique visits and match them with their purchases when you don't have auth users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model and Migrations
&lt;/h2&gt;

&lt;p&gt;Let's create a model and migrations first, to store our traffic data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:model Traffic &lt;span class="nt"&gt;-m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add necessary columns to traffic migration file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'traffic'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;ipAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ip'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'url'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ref'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'referer'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'utm_medium'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'utm_source'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'utm_medium'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'utm_campaign'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'utm_medium'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'data'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamps&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to track more query params, feel free to add other columns here.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;App\Models\Traffic.php&lt;/code&gt; cast the "data" to "json" or "array". In the data column we will store all request params, in case if some of them were not listed separately, to have everything collected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protected $casts = ['data' =&amp;gt; 'json'];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Columns explained
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;url&lt;/code&gt; we will store the current page url without query params.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ref&lt;/code&gt;, &lt;code&gt;utm_medium&lt;/code&gt;, &lt;code&gt;utm_source&lt;/code&gt;, &lt;code&gt;utm_campaign&lt;/code&gt; columns will contain the values from the eponymous query params.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;referer&lt;/code&gt; - we will store HTTP_REFERER to know from which website user came&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data&lt;/code&gt; column will contain an array of all query params from the url.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;uuid&lt;/code&gt; column will be the unique identifier for the user, will talk about it more below&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Middleware
&lt;/h2&gt;

&lt;p&gt;To track the params on user's each page visit, we will use a Middleware for that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:middleware TrafficMiddleware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Register your TrafficMiddleware
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;For Laravel 11&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add TrafficMiddleware::class to your &lt;code&gt;bootstrap/app.php&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```php bootstrap/app.php&lt;br&gt;
return Application::configure(basePath: dirname(&lt;strong&gt;DIR&lt;/strong&gt;))&lt;br&gt;
    -&amp;gt;withRouting(&lt;br&gt;
        ...&lt;br&gt;
    )&lt;br&gt;
    -&amp;gt;withMiddleware(function (Middleware $middleware) {&lt;br&gt;
        ...&lt;br&gt;
        $middleware-&amp;gt;web([&lt;br&gt;
            TrafficMiddleware::class&lt;br&gt;
        ])&lt;br&gt;
    })&lt;br&gt;
    -&amp;gt;withExceptions(function (Exceptions $exceptions) {&lt;br&gt;
        ...&lt;br&gt;
    })-&amp;gt;create();&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


**For Laravel 10**

Add TrafficMiddleware::class to your `app/Http/Kernel.php` file's web middleware group



```php app/Http/Kernel.php
protected $middlewareGroups = [
        ...
        'web' =&amp;gt; [
            ...
            TrafficMiddleware::class,
        ],
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  TrafficMiddleware
&lt;/h3&gt;

&lt;p&gt;As we do not have auth users, we should somehow identify unique users for visits. For that we will use &lt;code&gt;uuid&lt;/code&gt; and store it in session.&lt;br&gt;
I prefer to store it for 30 days, as users do not buy immediately, we still want to know from where they visited website for the first time.&lt;br&gt;
Feel free to change that to any days you want.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```php TrafficMiddleware.php&lt;br&gt;
if (request()-&amp;gt;hasCookie('uuid')) {&lt;br&gt;
    $uuid = request()-&amp;gt;cookie('uuid');&lt;br&gt;
} else {&lt;br&gt;
    $uuid = Str::uuid()-&amp;gt;toString();&lt;br&gt;
    Cookie::queue('uuid', $uuid, 60 * 24 * 30);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Traffic::create([&lt;br&gt;
    'ip' =&amp;gt; $request-&amp;gt;ip(),&lt;br&gt;
    'uuid' =&amp;gt; $uuid,&lt;br&gt;
    'url' =&amp;gt; Str::before($request-&amp;gt;getRequestUri(), '?'),&lt;br&gt;
    'ref' =&amp;gt; $request-&amp;gt;get('ref') ?? $request-&amp;gt;get('referrer'),&lt;br&gt;
    'utm_medium' =&amp;gt; $request-&amp;gt;get('utm_medium'),&lt;br&gt;
    'utm_source' =&amp;gt; $request-&amp;gt;get('utm_source'),&lt;br&gt;
    'utm_campaign' =&amp;gt; $request-&amp;gt;get('utm_campaign'),&lt;br&gt;
    'referer' =&amp;gt; Str::before($request-&amp;gt;server('HTTP_REFERER'), '?'),&lt;br&gt;
    'data' =&amp;gt; $request-&amp;gt;all(),&lt;br&gt;
]);&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Feel free to exclude any uri's that you don't want to store.

Full code for middleware. I cover it in try/catch in case something goes wrong, to not interrupt users visits.



```php TrafficMiddleware.php
&amp;lt;?php

namespace App\Http\Middleware;

use App\Models\Traffic;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;

class TrafficMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(Request): (Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        try {
            if (! Str::contains($request-&amp;gt;getRequestUri(), [
                '/admin',
                '/livewire',
                '/lemon-squeezy',
                '/api',
            ])) {

                if (request()-&amp;gt;hasCookie('uuid')) {
                    $uuid = request()-&amp;gt;cookie('uuid');
                } else {
                    $uuid = Str::uuid()-&amp;gt;toString();
                    Cookie::queue('uuid', $uuid, 60 * 24 * 30);
                }

                Traffic::create([
                    'ip' =&amp;gt; $request-&amp;gt;ip(),
                    'uuid' =&amp;gt; $uuid,
                    'url' =&amp;gt; Str::before($request-&amp;gt;getRequestUri(), '?'),
                    'ref' =&amp;gt; $request-&amp;gt;get('ref') ?? $request-&amp;gt;get('referrer'),
                    'utm_medium' =&amp;gt; $request-&amp;gt;get('utm_medium'),
                    'utm_source' =&amp;gt; $request-&amp;gt;get('utm_source'),
                    'utm_campaign' =&amp;gt; $request-&amp;gt;get('utm_campaign'),
                    'referer' =&amp;gt; Str::before($request-&amp;gt;server('HTTP_REFERER'), '?'),
                    'data' =&amp;gt; $request-&amp;gt;all(),
                ]);
            }

        } catch (\Exception $exception) {
            Log::error($exception);
        }

        return $next($request);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Match visit with purchase
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;
    This example is made for LemonSqueezy orders, but can be used with any other payments provider.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;When user makes a purchase, we need to match the purchase with the visit. For that we will use the &lt;code&gt;uuid&lt;/code&gt; that we stored in session.&lt;/p&gt;

&lt;p&gt;LemonSqueezy checkout url accepts custom params, so we will pass the &lt;code&gt;uuid&lt;/code&gt; to the checkout url and LemonSqueezy will return it back to us in the webhook.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add uuid to the checkout url
&lt;/h3&gt;

&lt;p&gt;In your plans section, get the &lt;code&gt;uuid&lt;/code&gt; from session and pass to the checkout url.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'buy_now_url'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'?checkout[custom][uuid]='&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$uuid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;br&gt;
To learn more about LemonSqueezy for Non-Auth Users check out the tutorial &lt;a href="https://dev.to/tutorials/lemonsqueezy-for-non-auth-users"&gt;here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
    For Vue users, to be sure that cookie is available for the first visit, create a new route to get the uuid from the cookie and do async request to get the uuid.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getUuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/uuid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;getUuid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;To connect our purchase with the visit, we will store the &lt;code&gt;uuid&lt;/code&gt; in the lemon_squeezy_orders table.&lt;/p&gt;

&lt;p&gt;Add new column to the &lt;code&gt;lemon_squeezy_orders&lt;/code&gt; table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'lemon_squeezy_orders'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the &lt;strong&gt;WebhookController&lt;/strong&gt;, we will match the purchase with the visit. (check &lt;a href="https://dev.totutorials/lemonsqueezy-webhooks-for-non-auth-users"&gt;LemonSqueezy Webhooks for Non-Auth Users&lt;/a&gt; for more details)&lt;/p&gt;

&lt;p&gt;Add the &lt;code&gt;uuid&lt;/code&gt; to the order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LemonSqueezy&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$orderModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="mf"&gt;...&lt;/span&gt;
    &lt;span class="s1"&gt;'uuid'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'meta'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'custom_data'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="mf"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! Now you can track your users visits and match them with their purchases.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>tracking</category>
      <category>analytics</category>
    </item>
    <item>
      <title>LemonSqueezy Webhooks for Non-Auth Users in Laravel</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Wed, 08 May 2024 12:51:58 +0000</pubDate>
      <link>https://dev.to/karakhanyans/lemonsqueezy-webhooks-for-non-auth-users-in-laravel-2dgk</link>
      <guid>https://dev.to/karakhanyans/lemonsqueezy-webhooks-for-non-auth-users-in-laravel-2dgk</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbio3zq47b1ayypgzv8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbio3zq47b1ayypgzv8n.png" alt="Thumb" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/lmsqueezy/laravel" rel="noopener noreferrer"&gt;Laravel LemonSqueezy&lt;/a&gt; package default webhooks are using billable model to store the orders in the database.&lt;br&gt;
But what if you want to handle webhooks for non-auth users?&lt;/p&gt;

&lt;p&gt;In this article, we will see how to handle LemonSqueezy webhooks for non-auth users in Laravel.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Install LemonSqueezy
&lt;/h2&gt;

&lt;p&gt;First, you need to install the LemonSqueezy package in your Laravel application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require lmsqueezy/laravel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the all installation steps in the &lt;a href="https://github.com/lmsqueezy/laravel" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Change the billable columns to nullable in lemon_squeezy_orders table
&lt;/h2&gt;

&lt;p&gt;In this example we are using the &lt;code&gt;orders&lt;/code&gt; table to store the orders for non-auth users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'lemon_squeezy_orders'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;unsignedBigInteger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'billable_id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;change&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'billable_type'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;change&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'customer_id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;change&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;dropIndex&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'billable_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'billable_type'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or modify them in main migration file after publishing them&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan vendor:publish &lt;span class="nt"&gt;--tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"lemon-squeezy-migrations"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also track user name and emails from lemon squeezy orders, so I added these columns to the &lt;code&gt;lemon_squeezy_orders&lt;/code&gt; table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'lemon_squeezy_orders'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user_email'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user_name'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Create a new route for webhooks
&lt;/h2&gt;

&lt;p&gt;As default LemonSqueezy webhooks are using the &lt;code&gt;billable&lt;/code&gt; model to store the orders in the database we need to create a new route for webhooks.&lt;/p&gt;

&lt;p&gt;Create a new controller &lt;code&gt;WebhookController&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:controller Webhooks/WebhookController &lt;span class="nt"&gt;--invoke&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new route for LemonSqueezy webhooks in your &lt;code&gt;routes/web.php&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controllers\Webhooks\WebhookController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'lemon-squeezy/webhook'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;WebhookController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Copy from LemonSqueezy WebhookController
&lt;/h2&gt;

&lt;p&gt;Open &lt;code&gt;vendor/lemonsqueezy/laravel/src/Http/Controllers/WebhookController.php&lt;/code&gt; file and copy the __construct(), __invoke() and handleOrderCreated() methods to your &lt;code&gt;WebhookController&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
You can extend your controller with LemonSqueezy Webhook Controller for the other methods if you don't need modifications there&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;For our case we need to modify our handleOrderCreated() method to store the orders for non-auth users.&lt;/p&gt;

&lt;p&gt;Instead of &lt;code&gt;$billable-&amp;gt;orders()&lt;/code&gt; we will use &lt;code&gt;LemonSqueezy::$orderModel&lt;/code&gt; to create the order in our database&lt;/p&gt;

&lt;p&gt;Remove &lt;code&gt;'customer_id' =&amp;gt; $attributes['customer_id'],&lt;/code&gt; from the &lt;code&gt;$order&lt;/code&gt; array as we are not using the &lt;code&gt;billable&lt;/code&gt; model.&lt;/p&gt;

&lt;p&gt;Add user_email and user_name to the &lt;code&gt;$order&lt;/code&gt; array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;handleOrderCreated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$payload&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;hasTable&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LemonSqueezy&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$orderModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getTable&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'data'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'attributes'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="nv"&gt;$order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LemonSqueezy&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$orderModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'lemon_squeezy_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'data'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'user_email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'user_email'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'user_name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'user_name'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'product_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'first_order_item'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'product_id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'variant_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'first_order_item'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'variant_id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'identifier'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'identifier'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'order_number'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'order_number'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'currency'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'currency'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'subtotal'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'subtotal'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'discount_total'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'discount_total'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'tax'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'tax'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'total'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'total'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'tax_name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'tax_name'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'status'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'receipt_url'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'urls'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'receipt'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'refunded'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'refunded'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'refunded_at'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'refunded_at'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;Carbon&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'refunded_at'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'ordered_at'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Carbon&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Event Listener
&lt;/h2&gt;

&lt;p&gt;Remove &lt;code&gt;OrderCreated::dispatch($billable, $order, $payload)&lt;/code&gt; as we are not using the &lt;code&gt;billable&lt;/code&gt; model.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
    Instead of OrderCreated event you can listen for &lt;code&gt;WebhookHandled&lt;/code&gt; event in your application.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Add  LemonSqueezyEventListener if you need to do additional actions after the order is created.&lt;br&gt;
For example you can send a welcome email with the steps how to use your app when user makes the order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Listeners&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;LemonSqueezy\Laravel\Events\WebhookHandled&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LemonSqueezyEventListener&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="mf"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;WebhookHandled&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'meta'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'event_name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'order_created'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Log&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Event handled'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'event'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'data'&lt;/span&gt;&lt;span class="p"&gt;]]);&lt;/span&gt;

            &lt;span class="nc"&gt;Notification&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'mail'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'user_email'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WelcomeNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'user_name'&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>laravel</category>
      <category>lemonsqueezy</category>
      <category>webhook</category>
    </item>
    <item>
      <title>Zero-Downtime Deployment with Laravel Forge</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Thu, 18 Apr 2024 09:48:26 +0000</pubDate>
      <link>https://dev.to/karakhanyans/zero-downtime-deployment-with-laravel-forge-3ho6</link>
      <guid>https://dev.to/karakhanyans/zero-downtime-deployment-with-laravel-forge-3ho6</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv4lb83fhm1wm20vqg5d0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv4lb83fhm1wm20vqg5d0.png" alt="Laravel Forge" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deploying web applications can be a repetitive and error-prone task. In this blog post, we'll introduce a Bash script designed to automate the deployment process for a web application hosted on a server. Let's dive into the details of the script and how it streamlines the deployment workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;Before diving into the deployment process, let's set up some initial configurations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;example.com
&lt;span class="nv"&gt;PROJECT_REPO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your_github_repo_name"&lt;/span&gt;
&lt;span class="nv"&gt;AMOUNT_KEEP_RELEASES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5

&lt;span class="nv"&gt;RELEASE_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s--%Y_%m_%d--%H_%M_%S&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;RELEASES_DIRECTORY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;/releases
&lt;span class="nv"&gt;DEPLOYMENT_DIRECTORY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$RELEASES_DIRECTORY&lt;/span&gt;/&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These variables define crucial aspects such as the domain name, project repository, and the number of releases to keep.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cloning Repository and Setup
&lt;/h3&gt;

&lt;p&gt;The script starts by creating a unique release directory and clones the project repository into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /home/forge/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASES_DIRECTORY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASES_DIRECTORY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

git clone &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PROJECT_REPO&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
git checkout &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FORGE_SITE_BRANCH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
git fetch origin &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FORGE_SITE_BRANCH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; FETCH_HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Environment Setup
&lt;/h3&gt;

&lt;p&gt;Next, the script copies the &lt;code&gt;.env&lt;/code&gt; file from the project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Copy ./.env file\n'&lt;/span&gt;
&lt;span class="nv"&gt;ENV_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;/.env
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt; ./.env
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nError: .env file is missing at %s.'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running Laravel Commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$FORGE_COMPOSER&lt;/span&gt; &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-dev&lt;/span&gt; &lt;span class="nt"&gt;--no-interaction&lt;/span&gt; &lt;span class="nt"&gt;--prefer-dist&lt;/span&gt; &lt;span class="nt"&gt;--optimize-autoloader&lt;/span&gt;

&lt;span class="o"&gt;(&lt;/span&gt; flock &lt;span class="nt"&gt;-w&lt;/span&gt; 10 9 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Restarting FPM...'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-S&lt;/span&gt; service &lt;span class="nv"&gt;$FORGE_PHP_FPM&lt;/span&gt; reload &lt;span class="o"&gt;)&lt;/span&gt; 9&amp;gt;/tmp/fpmlock

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; artisan &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="nv"&gt;$FORGE_PHP&lt;/span&gt; artisan migrate &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dependency Installation and Build
&lt;/h3&gt;

&lt;p&gt;The script installs NPM dependencies and generates necessary files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Installing NPM dependencies based on \"./package-lock.json\"\n'&lt;/span&gt;
npm &lt;span class="nb"&gt;install
printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Generating JS App files\n'&lt;/span&gt;
npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Linking Deployment Directory
&lt;/h3&gt;

&lt;p&gt;The script links the deployment directory to the current directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ !!! Link Deployment Directory !!!\n'&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$RELEASES_DIRECTORY&lt;/span&gt;/.successes
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; ~/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;/current &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-L&lt;/span&gt; ~/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;/current &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ~/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;/current
&lt;span class="k"&gt;fi
&lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-T&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEPLOYMENT_DIRECTORY&lt;/span&gt;&lt;span class="s2"&gt;/public"&lt;/span&gt; ~/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;/current
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Clean Up
&lt;/h3&gt;

&lt;p&gt;Lastly, the script performs clean-up tasks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Delete failed releases:\n'&lt;/span&gt;
&lt;span class="c"&gt;# Code for deleting failed releases&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Delete old successful releases:\n'&lt;/span&gt;
&lt;span class="c"&gt;# Code for deleting old successful releases&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Status - stored releases:\n'&lt;/span&gt;
&lt;span class="c"&gt;# Code for displaying stored releases&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\n✅ Deployment DONE: %s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEPLOYMENT_DIRECTORY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full Script
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SETUP #&lt;/span&gt;
&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yourdomain.com
&lt;span class="nv"&gt;PROJECT_REPO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git@github.com:your-team/repo.git"&lt;/span&gt;
&lt;span class="nv"&gt;AMOUNT_KEEP_RELEASES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5

&lt;span class="nv"&gt;RELEASE_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s--%Y_%m_%d--%H_%M_%S&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;RELEASES_DIRECTORY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;/releases
&lt;span class="nv"&gt;DEPLOYMENT_DIRECTORY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$RELEASES_DIRECTORY&lt;/span&gt;/&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;

&lt;span class="c"&gt;# stop script on error signal (-e) and undefined variables (-u)&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-eu&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Starting deployment %s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;cd&lt;/span&gt; /home/forge/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASES_DIRECTORY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASES_DIRECTORY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Clone GIT project from %s and checkout branch %s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PROJECT_REPO&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FORGE_SITE_BRANCH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
git clone &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PROJECT_REPO&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
git checkout &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FORGE_SITE_BRANCH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
git fetch origin &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FORGE_SITE_BRANCH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; FETCH_HEAD

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Copy ./.env file\n'&lt;/span&gt;
&lt;span class="nv"&gt;ENV_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;/.env
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt; ./.env
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nError: .env file is missing at %s.'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="nv"&gt;$FORGE_COMPOSER&lt;/span&gt; &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-dev&lt;/span&gt; &lt;span class="nt"&gt;--no-interaction&lt;/span&gt; &lt;span class="nt"&gt;--prefer-dist&lt;/span&gt; &lt;span class="nt"&gt;--optimize-autoloader&lt;/span&gt;

&lt;span class="o"&gt;(&lt;/span&gt; flock &lt;span class="nt"&gt;-w&lt;/span&gt; 10 9 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Restarting FPM...'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-S&lt;/span&gt; service &lt;span class="nv"&gt;$FORGE_PHP_FPM&lt;/span&gt; reload &lt;span class="o"&gt;)&lt;/span&gt; 9&amp;gt;/tmp/fpmlock

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; artisan &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="nv"&gt;$FORGE_PHP&lt;/span&gt; artisan migrate &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Installing NPM dependencies based on \"./package-lock.json\"\n'&lt;/span&gt;
npm &lt;span class="nb"&gt;install
printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Generating JS App files\n'&lt;/span&gt;
npm run build

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ !!! Link Deployment Directory !!!\n'&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$RELEASES_DIRECTORY&lt;/span&gt;/.successes
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; ~/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;/current &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-L&lt;/span&gt; ~/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;/current &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ~/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;/current
&lt;span class="k"&gt;fi
&lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-T&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEPLOYMENT_DIRECTORY&lt;/span&gt;&lt;span class="s2"&gt;/public"&lt;/span&gt; ~/&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;/current

&lt;span class="c"&gt;# Clean Up&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$RELEASES_DIRECTORY&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Delete failed releases:\n'&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-qvf&lt;/span&gt; .successes &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-vf&lt;/span&gt; .successes &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-vf&lt;/span&gt; .successes &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; | xargs &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt;
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No failed releases found."&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Delete old successful releases:\n'&lt;/span&gt;
&lt;span class="nv"&gt;AMOUNT_KEEP_RELEASES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;AMOUNT_KEEP_RELEASES-1&lt;span class="k"&gt;))&lt;/span&gt;
&lt;span class="nv"&gt;LINES_STORED_RELEASES_TO_DELETE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-maxdepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-mindepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-type&lt;/span&gt; d &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-printf&lt;/span&gt; &lt;span class="s1"&gt;'%T@\t%f\n'&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; -&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$AMOUNT_KEEP_RELEASES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LINES_STORED_RELEASES_TO_DELETE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-maxdepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-mindepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-type&lt;/span&gt; d &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-printf&lt;/span&gt; &lt;span class="s1"&gt;'%T@\t%f\n'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; -&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$AMOUNT_KEEP_RELEASES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 2-
  find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-maxdepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-mindepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-type&lt;/span&gt; d &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-printf&lt;/span&gt; &lt;span class="s1"&gt;'%T@\t%f\n'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; -&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$AMOUNT_KEEP_RELEASES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 2- | xargs &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'/{}/d'&lt;/span&gt; .successes
  find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-maxdepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-mindepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-type&lt;/span&gt; d &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RELEASE_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-printf&lt;/span&gt; &lt;span class="s1"&gt;'%T@\t%f\n'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; -&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$AMOUNT_KEEP_RELEASES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 2- | xargs &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt;
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nv"&gt;AMOUNT_KEEP_RELEASES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;AMOUNT_KEEP_RELEASES+1&lt;span class="k"&gt;))&lt;/span&gt;
  &lt;span class="nv"&gt;LINES_STORED_RELEASES_TOTAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-maxdepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-mindepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-type&lt;/span&gt; d &lt;span class="nt"&gt;-printf&lt;/span&gt; &lt;span class="s1"&gt;'%T@\t%f\n'&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'There are only %s successfully stored releases, which is less than or equal to your\ndefined %s releases to keep, so none of them got deleted.'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LINES_STORED_RELEASES_TOTAL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$AMOUNT_KEEP_RELEASES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nℹ️ Status - stored releases:\n'&lt;/span&gt;
find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-maxdepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-mindepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-type&lt;/span&gt; d &lt;span class="nt"&gt;-printf&lt;/span&gt; &lt;span class="s1"&gt;'%T@\t%f\n'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-nr&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 2-

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\n✅ Deployment DONE: %s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEPLOYMENT_DIRECTORY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Automation is key to improving deployment efficiency and reducing errors. By using this Bash script, you can streamline the deployment process for your web applications, saving time and ensuring consistency.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>forge</category>
      <category>larafast</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Top 3 questions people ask about Larafast</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Wed, 03 Apr 2024 11:46:57 +0000</pubDate>
      <link>https://dev.to/karakhanyans/top-3-questions-people-ask-about-larafast-4a05</link>
      <guid>https://dev.to/karakhanyans/top-3-questions-people-ask-about-larafast-4a05</guid>
      <description>&lt;p&gt;People ask a lot of questions about Larafast, I've chosen the top 3 of them to clarify.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Is it scalable and customizable?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, Larafast is a normal Laravel application, with pre-built features and components. It can be scaled and customized, and every Laravel package compatible with the boilerplate version (currently 11.x ) can be installed. &lt;br&gt;
Currently, it comes with Vue and Livewire stacks, but it can work with React and Svelte too. No limits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Does it have any dependencies on Larafast?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No, there are no dependencies, it can be treated as a fresh Laravel application, and the parts that you don't need can be removed or extended.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Why pay for Larafast if Laravel has free boilerplates?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Laravel has a lot of other boilerplates and CMS's that are free, and that's true. What makes Larafast different is that it combines the features and components that most people need to run their apps fast. &lt;/p&gt;

&lt;p&gt;Other boilerplates need a lot of configurations and have a lot of dependencies, Larafast on the other hand created to speed up the development process and skip setting up Payments, SEO, Admin, etc. &lt;/p&gt;

&lt;p&gt;Imagine having a ready-to-go boilerplate under your hands every time, which needs to change the texts and logo, and you are ready to go. That's Larafast.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Laravel LemonSqueezy for Non-Auth Users</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Wed, 27 Mar 2024 08:28:53 +0000</pubDate>
      <link>https://dev.to/karakhanyans/laravel-lemonsqueezy-for-non-auth-users-1lg1</link>
      <guid>https://dev.to/karakhanyans/laravel-lemonsqueezy-for-non-auth-users-1lg1</guid>
      <description>&lt;h3&gt;
  
  
  Extending LemonSqueezy to Non-Registered Users: A Practical Guide
&lt;/h3&gt;

&lt;p&gt;When it comes to online shopping, making the checkout process as smooth as possible is crucial. Many Laravel developers rely on LemonSqueezy, a handy package for managing transactions. However, &lt;a href="https://github.com/lmsqueezy/laravel" rel="noopener noreferrer"&gt;Laravel LemonSqueezy&lt;/a&gt; is primarily designed for registered users, which can be a problem for guests. &lt;/p&gt;

&lt;p&gt;But fear not, there's a simple solution to make LemonSqueezy work for everyone, whether they're logged in or not.&lt;/p&gt;

&lt;p&gt;By default, Laravel LemonSqueezy's checkout features are geared towards registered users. But what about those who are just browsing without an account? That's where the &lt;code&gt;LemonSqueezyService&lt;/code&gt; comes into play. It's a nifty tool that allows you to extend LemonSqueezy's capabilities to non-registered users hassle-free.&lt;/p&gt;

&lt;p&gt;To get started, make sure you've added the &lt;code&gt;LemonSqueezyServiceProvider&lt;/code&gt; to your Laravel app. Once that's done, you can use the &lt;code&gt;LemonSqueezyService&lt;/code&gt; to interact with LemonSqueezy's API and give non-registered users access to product payment links.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add LemonSqueezy configs into services.php
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
    &lt;span class="s1"&gt;'lemonsqueezy'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'base_url'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'https://api.lemonsqueezy.com/v1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'key'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'LEMON_SQUEEZY_API_KEY'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'store'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'LEMON_SQUEEZY_STORE'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy Service and ServiceProvider from the following Gist&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/karakhanyans/95703b69322479c1968f41aeb8069aba" rel="noopener noreferrer"&gt;https://gist.github.com/karakhanyans/95703b69322479c1968f41aeb8069aba&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or use &lt;a href="http://larafast.com/" rel="noopener noreferrer"&gt;Larafast&lt;/a&gt; Laravel Boilerplate which comes with LemonSqueezy and Stripe integrated. &lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Product Info
&lt;/h3&gt;

&lt;p&gt;The first step is fetching product details to display on your site. You can do this using the &lt;code&gt;products()&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;LemonSqueezyService&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;products&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dealing with Variants
&lt;/h3&gt;

&lt;p&gt;For products with different options or variants, or even those with just one price, you'll need to handle things a bit differently. The &lt;code&gt;variants()&lt;/code&gt; method helps you fetch relevant information based on a specific product ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;variants&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$productId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'variants?filter[product_id]='&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$productId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generating Checkout URLs
&lt;/h3&gt;

&lt;p&gt;For products with a single variant, you can use the &lt;code&gt;buy_now_url&lt;/code&gt; attribute to create a direct checkout link. To include a discount code, simply append &lt;code&gt;?checkout%5Bdiscount_code%5D=YOUR_DISCOUNT_CODE&lt;/code&gt; to the URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'buy_now_url'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;'?checkout%5Bdiscount_code%5D=YOUR_DISCOUNT_CODE'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For products with multiple variants, you'll need to generate checkout URLs dynamically using the &lt;code&gt;checkout()&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$variant&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Implementation details&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example Implementation
&lt;/h3&gt;

&lt;p&gt;Here's how you can use the &lt;code&gt;LemonSqueezyService&lt;/code&gt; to fetch and display product information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Fetch products (cached for performance)&lt;/span&gt;
&lt;span class="nv"&gt;$products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;rememberForever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'lemonsqueezy-products'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;LemonSqueezyService&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;products&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Process product data&lt;/span&gt;
&lt;span class="nv"&gt;$products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$products&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'data'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'attributes'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'published'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;sortByDesc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'attributes'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'price'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Processing logic&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Use $products variable in your view files for display&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By following these steps, you can provide a seamless shopping experience for both registered and non-registered users, leveraging the power of LemonSqueezy in your Laravel application.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Laravel SaaS Boilerplate</title>
      <dc:creator>Serg</dc:creator>
      <pubDate>Thu, 07 Mar 2024 16:25:40 +0000</pubDate>
      <link>https://dev.to/karakhanyans/laravel-saas-boilerplate-5ece</link>
      <guid>https://dev.to/karakhanyans/laravel-saas-boilerplate-5ece</guid>
      <description>&lt;p&gt;Hey Laravel Devs, I'm Serg, a Certified Laravel developer with 7 years of experience with the Framework. &lt;/p&gt;

&lt;p&gt;I have combined my experience and knowledge in this SaaS boilerplate, with the latest technologies that all of you already love, like Filament, Tailwind, etc. &lt;/p&gt;

&lt;p&gt;It has payments, admin, blog, SEO, user management, and a lot of beautiful Vue+Tailwind components to save you a lot of time. &lt;/p&gt;

&lt;p&gt;Hope to hear your feedback.&lt;/p&gt;

&lt;p&gt;Details -&amp;gt; &lt;a href="https://larafast.com" rel="noopener noreferrer"&gt;https://larafast.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>saas</category>
    </item>
  </channel>
</rss>
