[{"data":1,"prerenderedAt":998},["ShallowReactive",2],{"\u002Farticles\u002Fembrace-the-framework-order-processing-with-pipelines":3,"article-series:embrace-the-framework":945},{"id":4,"title":5,"body":6,"description":928,"draft":929,"extension":930,"meta":931,"navigation":156,"path":932,"published":933,"seo":934,"seoDescription":935,"series":936,"seriesOrder":937,"stem":938,"tags":939,"updated":943,"__hash__":944},"articles\u002Farticles\u002Fembrace-the-framework-order-processing-with-pipelines.md","Embrace the Framework: Break Order Processing Into Steps With Pipelines",{"type":7,"value":8,"toc":920},"minimark",[9,13,16,19,24,27,173,176,179,183,186,189,349,352,356,359,627,634,637,765,769,772,775,778,782,785,788,890,893,897,900,903,913,916],[10,11,12],"p",{},"Some problems are about transforming a group of data. Collections are a very good fit for those.",[10,14,15],{},"Other problems are about moving one piece of work through a sequence of decisions. An order needs its address checked, its stock reserved, its pricing confirmed, its shipping calculated, and perhaps its risk assessed. Each step is related, but each has a different responsibility.",[10,17,18],{},"That is where Laravel Pipelines can help.",[20,21,23],"h2",{"id":22},"the-service-method-that-keeps-growing","The service method that keeps growing",[10,25,26],{},"A checkout service often starts in a perfectly reasonable place:",[28,29,34],"pre",{"className":30,"code":31,"language":32,"meta":33,"style":33},"language-php shiki shiki-themes github-light github-dark","public function process(Order $order): Order\n{\n    $this->validateAddress($order);\n    $this->reserveStock($order);\n    $this->applyContractPricing($order);\n    $this->calculateShipping($order);\n    $this->runFraudChecks($order);\n    $this->saveOrder($order);\n\n    return $order;\n}\n","php","",[35,36,37,70,76,91,103,115,127,139,151,158,167],"code",{"__ignoreMap":33},[38,39,42,46,49,53,57,61,64,67],"span",{"class":40,"line":41},"line",1,[38,43,45],{"class":44},"szBVR","public",[38,47,48],{"class":44}," function",[38,50,52],{"class":51},"sScJk"," process",[38,54,56],{"class":55},"sVt8B","(",[38,58,60],{"class":59},"sj4cs","Order",[38,62,63],{"class":55}," $order)",[38,65,66],{"class":44},":",[38,68,69],{"class":59}," Order\n",[38,71,73],{"class":40,"line":72},2,[38,74,75],{"class":55},"{\n",[38,77,79,82,85,88],{"class":40,"line":78},3,[38,80,81],{"class":59},"    $this",[38,83,84],{"class":44},"->",[38,86,87],{"class":51},"validateAddress",[38,89,90],{"class":55},"($order);\n",[38,92,94,96,98,101],{"class":40,"line":93},4,[38,95,81],{"class":59},[38,97,84],{"class":44},[38,99,100],{"class":51},"reserveStock",[38,102,90],{"class":55},[38,104,106,108,110,113],{"class":40,"line":105},5,[38,107,81],{"class":59},[38,109,84],{"class":44},[38,111,112],{"class":51},"applyContractPricing",[38,114,90],{"class":55},[38,116,118,120,122,125],{"class":40,"line":117},6,[38,119,81],{"class":59},[38,121,84],{"class":44},[38,123,124],{"class":51},"calculateShipping",[38,126,90],{"class":55},[38,128,130,132,134,137],{"class":40,"line":129},7,[38,131,81],{"class":59},[38,133,84],{"class":44},[38,135,136],{"class":51},"runFraudChecks",[38,138,90],{"class":55},[38,140,142,144,146,149],{"class":40,"line":141},8,[38,143,81],{"class":59},[38,145,84],{"class":44},[38,147,148],{"class":51},"saveOrder",[38,150,90],{"class":55},[38,152,154],{"class":40,"line":153},9,[38,155,157],{"emptyLinePlaceholder":156},true,"\n",[38,159,161,164],{"class":40,"line":160},10,[38,162,163],{"class":44},"    return",[38,165,166],{"class":55}," $order;\n",[38,168,170],{"class":40,"line":169},11,[38,171,172],{"class":55},"}\n",[10,174,175],{},"This is clear at first. The trouble comes when each method starts to have exceptions, dependencies, early exits, logging, and special cases. The service can become a large coordinator that knows far too much about every stage of the process.",[10,177,178],{},"It is still functional code, but it makes change more expensive. Adding a new check means touching a central class. Reusing just one processing stage means either duplicating it or pulling methods apart. Testing a single rule can require setting up the whole workflow.",[20,180,182],{"id":181},"a-pipeline-gives-each-stage-a-focused-job","A Pipeline gives each stage a focused job",[10,184,185],{},"Laravel's Pipeline class lets us pass an object through a sequence of small classes, often called pipes.",[10,187,188],{},"Our order service can focus on the workflow itself:",[28,190,192],{"className":30,"code":191,"language":32,"meta":33,"style":33},"use Illuminate\\Pipeline\\Pipeline;\n\npublic function process(Order $order): Order\n{\n    return app(Pipeline::class)\n        ->send($order)\n        ->through([\n            ValidateDeliveryAddress::class,\n            ReserveStock::class,\n            ApplyContractPricing::class,\n            CalculateShipping::class,\n            RunFraudChecks::class,\n            PersistOrder::class,\n        ])\n        ->thenReturn();\n}\n",[35,193,194,205,209,227,231,249,260,270,280,289,298,307,317,327,333,344],{"__ignoreMap":33},[38,195,196,199,202],{"class":40,"line":41},[38,197,198],{"class":44},"use",[38,200,201],{"class":59}," Illuminate\\Pipeline\\Pipeline",[38,203,204],{"class":55},";\n",[38,206,207],{"class":40,"line":72},[38,208,157],{"emptyLinePlaceholder":156},[38,210,211,213,215,217,219,221,223,225],{"class":40,"line":78},[38,212,45],{"class":44},[38,214,48],{"class":44},[38,216,52],{"class":51},[38,218,56],{"class":55},[38,220,60],{"class":59},[38,222,63],{"class":55},[38,224,66],{"class":44},[38,226,69],{"class":59},[38,228,229],{"class":40,"line":93},[38,230,75],{"class":55},[38,232,233,235,238,240,243,246],{"class":40,"line":105},[38,234,163],{"class":44},[38,236,237],{"class":51}," app",[38,239,56],{"class":55},[38,241,242],{"class":59},"Pipeline",[38,244,245],{"class":44},"::class",[38,247,248],{"class":55},")\n",[38,250,251,254,257],{"class":40,"line":117},[38,252,253],{"class":44},"        ->",[38,255,256],{"class":51},"send",[38,258,259],{"class":55},"($order)\n",[38,261,262,264,267],{"class":40,"line":129},[38,263,253],{"class":44},[38,265,266],{"class":51},"through",[38,268,269],{"class":55},"([\n",[38,271,272,275,277],{"class":40,"line":141},[38,273,274],{"class":59},"            ValidateDeliveryAddress",[38,276,245],{"class":44},[38,278,279],{"class":55},",\n",[38,281,282,285,287],{"class":40,"line":153},[38,283,284],{"class":59},"            ReserveStock",[38,286,245],{"class":44},[38,288,279],{"class":55},[38,290,291,294,296],{"class":40,"line":160},[38,292,293],{"class":59},"            ApplyContractPricing",[38,295,245],{"class":44},[38,297,279],{"class":55},[38,299,300,303,305],{"class":40,"line":169},[38,301,302],{"class":59},"            CalculateShipping",[38,304,245],{"class":44},[38,306,279],{"class":55},[38,308,310,313,315],{"class":40,"line":309},12,[38,311,312],{"class":59},"            RunFraudChecks",[38,314,245],{"class":44},[38,316,279],{"class":55},[38,318,320,323,325],{"class":40,"line":319},13,[38,321,322],{"class":59},"            PersistOrder",[38,324,245],{"class":44},[38,326,279],{"class":55},[38,328,330],{"class":40,"line":329},14,[38,331,332],{"class":55},"        ])\n",[38,334,336,338,341],{"class":40,"line":335},15,[38,337,253],{"class":44},[38,339,340],{"class":51},"thenReturn",[38,342,343],{"class":55},"();\n",[38,345,347],{"class":40,"line":346},16,[38,348,172],{"class":55},[10,350,351],{},"The sequence is visible immediately. It is also easy to change: inserting a new stage is a deliberate change to the workflow rather than another concern hidden inside a large method.",[20,353,355],{"id":354},"a-pipe-should-be-small-and-honest","A pipe should be small and honest",[10,357,358],{},"Here is a simple stock reservation pipe:",[28,360,362],{"className":30,"code":361,"language":32,"meta":33,"style":33},"\u003C?php\n\nnamespace App\\Pipelines\\OrderProcessing;\n\nuse App\\Exceptions\\InsufficientStock;\nuse App\\Models\\Order;\nuse Closure;\n\nclass ReserveStock\n{\n    public function handle(Order $order, Closure $next): mixed\n    {\n        foreach ($order->items as $item) {\n            if (! $item->product->hasAvailableStock($item->quantity)) {\n                throw new InsufficientStock($item->product);\n            }\n        }\n\n        $order->items->each(fn ($item) =>\n            $item->product->reserveStock($item->quantity)\n        );\n\n        return $next($order);\n    }\n}\n",[35,363,364,372,376,386,390,399,408,417,421,429,433,461,466,485,517,535,540,546,551,575,596,602,607,616,622],{"__ignoreMap":33},[38,365,366,369],{"class":40,"line":41},[38,367,368],{"class":44},"\u003C?",[38,370,371],{"class":59},"php\n",[38,373,374],{"class":40,"line":72},[38,375,157],{"emptyLinePlaceholder":156},[38,377,378,381,384],{"class":40,"line":78},[38,379,380],{"class":44},"namespace",[38,382,383],{"class":51}," App\\Pipelines\\OrderProcessing",[38,385,204],{"class":55},[38,387,388],{"class":40,"line":93},[38,389,157],{"emptyLinePlaceholder":156},[38,391,392,394,397],{"class":40,"line":105},[38,393,198],{"class":44},[38,395,396],{"class":59}," App\\Exceptions\\InsufficientStock",[38,398,204],{"class":55},[38,400,401,403,406],{"class":40,"line":117},[38,402,198],{"class":44},[38,404,405],{"class":59}," App\\Models\\Order",[38,407,204],{"class":55},[38,409,410,412,415],{"class":40,"line":129},[38,411,198],{"class":44},[38,413,414],{"class":59}," Closure",[38,416,204],{"class":55},[38,418,419],{"class":40,"line":141},[38,420,157],{"emptyLinePlaceholder":156},[38,422,423,426],{"class":40,"line":153},[38,424,425],{"class":44},"class",[38,427,428],{"class":51}," ReserveStock\n",[38,430,431],{"class":40,"line":160},[38,432,75],{"class":55},[38,434,435,438,440,443,445,447,450,453,456,458],{"class":40,"line":169},[38,436,437],{"class":44},"    public",[38,439,48],{"class":44},[38,441,442],{"class":51}," handle",[38,444,56],{"class":55},[38,446,60],{"class":59},[38,448,449],{"class":55}," $order, ",[38,451,452],{"class":59},"Closure",[38,454,455],{"class":55}," $next)",[38,457,66],{"class":44},[38,459,460],{"class":44}," mixed\n",[38,462,463],{"class":40,"line":309},[38,464,465],{"class":55},"    {\n",[38,467,468,471,474,476,479,482],{"class":40,"line":319},[38,469,470],{"class":44},"        foreach",[38,472,473],{"class":55}," ($order",[38,475,84],{"class":44},[38,477,478],{"class":55},"items ",[38,480,481],{"class":44},"as",[38,483,484],{"class":55}," $item) {\n",[38,486,487,490,493,496,499,501,504,506,509,512,514],{"class":40,"line":329},[38,488,489],{"class":44},"            if",[38,491,492],{"class":55}," (",[38,494,495],{"class":44},"!",[38,497,498],{"class":55}," $item",[38,500,84],{"class":44},[38,502,503],{"class":55},"product",[38,505,84],{"class":44},[38,507,508],{"class":51},"hasAvailableStock",[38,510,511],{"class":55},"($item",[38,513,84],{"class":44},[38,515,516],{"class":55},"quantity)) {\n",[38,518,519,522,525,528,530,532],{"class":40,"line":335},[38,520,521],{"class":44},"                throw",[38,523,524],{"class":44}," new",[38,526,527],{"class":59}," InsufficientStock",[38,529,511],{"class":55},[38,531,84],{"class":44},[38,533,534],{"class":55},"product);\n",[38,536,537],{"class":40,"line":346},[38,538,539],{"class":55},"            }\n",[38,541,543],{"class":40,"line":542},17,[38,544,545],{"class":55},"        }\n",[38,547,549],{"class":40,"line":548},18,[38,550,157],{"emptyLinePlaceholder":156},[38,552,554,557,559,562,564,567,569,572],{"class":40,"line":553},19,[38,555,556],{"class":55},"        $order",[38,558,84],{"class":44},[38,560,561],{"class":55},"items",[38,563,84],{"class":44},[38,565,566],{"class":51},"each",[38,568,56],{"class":55},[38,570,571],{"class":44},"fn",[38,573,574],{"class":55}," ($item) =>\n",[38,576,578,581,583,585,587,589,591,593],{"class":40,"line":577},20,[38,579,580],{"class":55},"            $item",[38,582,84],{"class":44},[38,584,503],{"class":55},[38,586,84],{"class":44},[38,588,100],{"class":51},[38,590,511],{"class":55},[38,592,84],{"class":44},[38,594,595],{"class":55},"quantity)\n",[38,597,599],{"class":40,"line":598},21,[38,600,601],{"class":55},"        );\n",[38,603,605],{"class":40,"line":604},22,[38,606,157],{"emptyLinePlaceholder":156},[38,608,610,613],{"class":40,"line":609},23,[38,611,612],{"class":44},"        return",[38,614,615],{"class":55}," $next($order);\n",[38,617,619],{"class":40,"line":618},24,[38,620,621],{"class":55},"    }\n",[38,623,625],{"class":40,"line":624},25,[38,626,172],{"class":55},[10,628,629,630,633],{},"This class does not need to know whether shipping has been calculated, whether the order will be persisted, or what happens after it calls ",[35,631,632],{},"$next",". It has one responsibility: ensure stock is available and reserve it.",[10,635,636],{},"That narrow focus makes the class easier to test too.",[28,638,640],{"className":30,"code":639,"language":32,"meta":33,"style":33},"it('stops processing when an item is out of stock', function () {\n    $order = Order::factory()->withOutOfStockItem()->make();\n\n    expect(fn () => app(ReserveStock::class)->handle($order, fn () => null))\n        ->toThrow(InsufficientStock::class);\n});\n",[35,641,642,662,696,700,743,760],{"__ignoreMap":33},[38,643,644,647,649,653,656,659],{"class":40,"line":41},[38,645,646],{"class":51},"it",[38,648,56],{"class":55},[38,650,652],{"class":651},"sZZnC","'stops processing when an item is out of stock'",[38,654,655],{"class":55},", ",[38,657,658],{"class":44},"function",[38,660,661],{"class":55}," () {\n",[38,663,664,667,670,673,676,679,682,684,687,689,691,694],{"class":40,"line":72},[38,665,666],{"class":55},"    $order ",[38,668,669],{"class":44},"=",[38,671,672],{"class":59}," Order",[38,674,675],{"class":44},"::",[38,677,678],{"class":51},"factory",[38,680,681],{"class":55},"()",[38,683,84],{"class":44},[38,685,686],{"class":51},"withOutOfStockItem",[38,688,681],{"class":55},[38,690,84],{"class":44},[38,692,693],{"class":51},"make",[38,695,343],{"class":55},[38,697,698],{"class":40,"line":78},[38,699,157],{"emptyLinePlaceholder":156},[38,701,702,705,707,709,712,715,717,720,722,725,727,730,733,735,737,740],{"class":40,"line":93},[38,703,704],{"class":51},"    expect",[38,706,56],{"class":55},[38,708,571],{"class":44},[38,710,711],{"class":55}," () => ",[38,713,714],{"class":51},"app",[38,716,56],{"class":55},[38,718,719],{"class":59},"ReserveStock",[38,721,245],{"class":44},[38,723,724],{"class":55},")",[38,726,84],{"class":44},[38,728,729],{"class":51},"handle",[38,731,732],{"class":55},"($order, ",[38,734,571],{"class":44},[38,736,711],{"class":55},[38,738,739],{"class":59},"null",[38,741,742],{"class":55},"))\n",[38,744,745,747,750,752,755,757],{"class":40,"line":105},[38,746,253],{"class":44},[38,748,749],{"class":51},"toThrow",[38,751,56],{"class":55},[38,753,754],{"class":59},"InsufficientStock",[38,756,245],{"class":44},[38,758,759],{"class":55},");\n",[38,761,762],{"class":40,"line":117},[38,763,764],{"class":55},"});\n",[20,766,768],{"id":767},"the-order-of-the-steps-is-part-of-the-design","The order of the steps is part of the design",[10,770,771],{},"A Pipeline makes the sequence explicit, which is useful because order matters.",[10,773,774],{},"We should validate an address before calculating shipping. We should confirm stock before accepting an order. We may need contract pricing before fraud checks if the order value affects the risk rules.",[10,776,777],{},"Keeping the order in one place makes those decisions visible during code review. It also gives the team a clear answer to the question: what exactly happens when an order is processed?",[20,779,781],{"id":780},"do-not-use-a-pipeline-just-because-it-exists","Do not use a Pipeline just because it exists",[10,783,784],{},"A Pipeline has some overhead. For two small operations, a simple method may be easier to read. It becomes valuable when the process has several independent stages, stages need their own tests, or the sequence is likely to grow.",[10,786,787],{},"Pipelines are also not a replacement for transactions. If the workflow changes data in several places, the surrounding service still needs to decide where the database transaction begins and ends.",[28,789,791],{"className":30,"code":790,"language":32,"meta":33,"style":33},"public function process(Order $order): Order\n{\n    return DB::transaction(fn () =>\n        app(Pipeline::class)\n            ->send($order)\n            ->through($this->pipes)\n            ->thenReturn()\n    );\n}\n",[35,792,793,811,815,834,847,856,872,881,886],{"__ignoreMap":33},[38,794,795,797,799,801,803,805,807,809],{"class":40,"line":41},[38,796,45],{"class":44},[38,798,48],{"class":44},[38,800,52],{"class":51},[38,802,56],{"class":55},[38,804,60],{"class":59},[38,806,63],{"class":55},[38,808,66],{"class":44},[38,810,69],{"class":59},[38,812,813],{"class":40,"line":72},[38,814,75],{"class":55},[38,816,817,819,822,824,827,829,831],{"class":40,"line":78},[38,818,163],{"class":44},[38,820,821],{"class":59}," DB",[38,823,675],{"class":44},[38,825,826],{"class":51},"transaction",[38,828,56],{"class":55},[38,830,571],{"class":44},[38,832,833],{"class":55}," () =>\n",[38,835,836,839,841,843,845],{"class":40,"line":93},[38,837,838],{"class":51},"        app",[38,840,56],{"class":55},[38,842,242],{"class":59},[38,844,245],{"class":44},[38,846,248],{"class":55},[38,848,849,852,854],{"class":40,"line":105},[38,850,851],{"class":44},"            ->",[38,853,256],{"class":51},[38,855,259],{"class":55},[38,857,858,860,862,864,867,869],{"class":40,"line":117},[38,859,851],{"class":44},[38,861,266],{"class":51},[38,863,56],{"class":55},[38,865,866],{"class":59},"$this",[38,868,84],{"class":44},[38,870,871],{"class":55},"pipes)\n",[38,873,874,876,878],{"class":40,"line":129},[38,875,851],{"class":44},[38,877,340],{"class":51},[38,879,880],{"class":55},"()\n",[38,882,883],{"class":40,"line":141},[38,884,885],{"class":55},"    );\n",[38,887,888],{"class":40,"line":153},[38,889,172],{"class":55},[10,891,892],{},"The Pipeline describes the business process. The service still owns the wider application concerns, such as transactions and deciding which pipes apply.",[20,894,896],{"id":895},"collections-and-pipelines-solve-different-problems","Collections and Pipelines solve different problems",[10,898,899],{},"The collection examples earlier in this series took a group of orders and helped us decide what each group meant. This example takes one order and moves it through a defined process.",[10,901,902],{},"That distinction is useful:",[904,905,906,910],"ul",{},[907,908,909],"li",{},"Use a Collection when you are transforming or summarising a group of things.",[907,911,912],{},"Use a Pipeline when one thing needs to move through a sequence of focused stages.",[10,914,915],{},"Both approaches lean into tools Laravel already provides. More importantly, both help the code describe the work the application is actually doing.",[917,918,919],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":33,"searchDepth":72,"depth":72,"links":921},[922,923,924,925,926,927],{"id":22,"depth":72,"text":23},{"id":181,"depth":72,"text":182},{"id":354,"depth":72,"text":355},{"id":767,"depth":72,"text":768},{"id":780,"depth":72,"text":781},{"id":895,"depth":72,"text":896},"Laravel Pipelines let complex workflows grow one focused, testable step at a time instead of one large service method.",false,"md",{},"\u002Farticles\u002Fembrace-the-framework-order-processing-with-pipelines","2026-07-31",{"title":5,"description":928},"Learn how Laravel Pipelines make order processing easier to test, extend, and understand with focused processing steps.","embrace-the-framework","4","articles\u002Fembrace-the-framework-order-processing-with-pipelines",[940,32,941,942],"laravel","pipelines","ecommerce",null,"LDoVZU8mnp-dEP2AFFgY56I5BF9Q7239m980nFGGLG4",[946,951,956,961,966,971,972,977,982,986,990,994],{"path":947,"title":948,"published":949,"series":936,"seriesOrder":950},"\u002Farticles\u002Fembrace-the-framework-custom-collections-for-subscriptions","Embrace the Framework: Put Subscription Business Rules in a Custom Collection","2026-07-28","3",{"path":952,"title":953,"published":954,"series":936,"seriesOrder":955},"\u002Farticles\u002Fembrace-the-framework-customer-eligibility-with-custom-collections","Embrace the Framework: Make Eligibility Rules Read Like Business Policy","2026-08-04","6",{"path":957,"title":958,"published":959,"series":936,"seriesOrder":960},"\u002Farticles\u002Fembrace-the-framework-operational-reports-with-collections","Embrace the Framework: Build Clear Operational Reports With Collections","2026-08-02","5",{"path":962,"title":963,"published":964,"series":936,"seriesOrder":965},"\u002Farticles\u002Fembrace-the-framework-order-fulfilment-with-collections","Embrace the Framework: Make Order Fulfilment Clearer With Collections","2026-07-25","2",{"path":967,"title":968,"published":969,"series":936,"seriesOrder":970},"\u002Farticles\u002Fembrace-the-framework-order-processing-pipeline-that-can-grow","Embrace the Framework: Build an Order Processing Pipeline That Can Grow","2026-08-06","7",{"path":932,"title":5,"published":933,"series":936,"seriesOrder":937},{"path":973,"title":974,"published":975,"series":936,"seriesOrder":976},"\u002Farticles\u002Fembrace-the-framework-supplier-imports-with-collections-and-pipelines","Embrace the Framework: Combine Collections and Pipelines for Reliable Supplier Imports","2026-08-08","8",{"path":978,"title":979,"published":980,"series":936,"seriesOrder":981},"\u002Farticles\u002Fembrace-the-framework-why-working-with-laravel-beats-working-around-it","Embrace the Framework: Why Working With Laravel Beats Working Around It","2026-07-23","1",{"path":983,"title":984,"published":985,"series":943,"seriesOrder":943},"\u002Farticles\u002Fsimple-search-helper","A Simple Laravel Search Helper","2023-08-06",{"path":987,"title":988,"published":989,"series":943,"seriesOrder":943},"\u002Farticles\u002Fsvg-tidy-local-svg-optimiser","SVG Tidy: Clean and Optimise SVGs Locally","2026-07-21",{"path":991,"title":992,"published":993,"series":943,"seriesOrder":943},"\u002Farticles\u002Ftools-i-use","Tools I Use","2024-05-26",{"path":995,"title":996,"published":997,"series":943,"seriesOrder":943},"\u002Farticles\u002Fwelcome","Welcome","2023-08-05",1785659753486]