$context The context to pass to the template * @param string|null $pushUrl Optional URL to push to browser history * * @return Response Response containing all rendered blocks with OOB context */ protected function htmxOobResponse(string $templateName, array $blockNames, array $context = [], ?string $pushUrl = null): Response { $html = ''; // Add a flag to the context so templates can conditionally add the hx-swap-oob attribute. $oobContext = $context + ['htmx_oob_swap' => true]; foreach ($blockNames as $blockName) { // Use renderBlockView() to get the raw HTML string for each block. $html .= $this->renderBlockView($templateName, $blockName, $oobContext); } $response = new Response($html); // Set HX-Push-Url header if URL is provided if (null !== $pushUrl) { $response->headers->set('HX-Push-Url', $pushUrl); } return $response; } /** * Creates a redirect response that works correctly with HTMX requests. * * For HTMX requests, returns a 200 response with HX-Redirect header, * which triggers a full page navigation (avoiding CORS issues with cross-origin redirects). * For regular requests, returns a standard HTTP redirect. */ protected function htmxRedirect(Request $request, string $url): Response { if ($request->headers->has('HX-Request')) { return new HxRedirectResponse($url); } return $this->redirect($url); } }