Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sulu Form Landing Page Bundle Laravel Package

innomedio/sulu-form-landing-page-bundle

A Sulu CMS bundle for building form-enabled landing pages. It lets editors integrate and manage forms directly within landing pages, simplifying form setup and rendering for lead-generation and marketing pages.

View on GitHub
Deep Wiki
Context7

Getting Started

What it is: a small Symfony bundle for Sulu CMS that lets an editor pick a page (or URL) as the post-submit destination for a Sulu form, so the frontend controller issues a redirect instead of re-rendering the form with a success message. It is a single-purpose glue package, not a framework.

Prerequisites (verify in composer.json before adopting):

  • Sulu 2.x with sulu/form-bundle installed and at least one working form.
  • A Symfony version compatible with the package's constraints. v3.0.1 is a Symfony-constraint refresh — read the require block rather than trusting the tag number, and check which Symfony majors are actually allowed (expect 6.4/7.x by now). If you are still on Symfony 5.4, you likely need a 2.x line of this bundle, not 3.x.
  • Registration as a Symfony bundle — Sulu projects rarely rely on Flex auto-discovery, so expect a manual entry.

Minimal setup:

composer require innomedio/sulu-form-landing-page-bundle
// config/bundles.php
Innomedio\SuluFormLandingPageBundle\InnomedioSuluFormLandingPageBundle::class => ['all' => true],
bin/console cache:clear
bin/console debug:event-dispatcher   # find which form event the listener subscribes to

Where to look first, in this order:

  1. vendor/innomedio/sulu-form-landing-page-bundle/README.md — almost certainly contains the one XML snippet you need.
  2. src/EventListener/ (or src/EventSubscriber/) — this is where the redirect decision lives; read it before trusting the README.
  3. Resources/config/services.yaml + DependencyInjection/Configuration.php — the only place config keys (default target, enabled form keys) will be documented.
  4. Resources/translations/ — confirms whether the new admin field is labelled "Landing Page" or something else in the form editor.

First use case: add a single_page_selection-style property named something like landingPage to an existing contact form XML in config/forms/contact.xml, clear the cache, refresh the Sulu admin, open the form, pick a thank-you page, submit the frontend form, and assert a 302 to that page's URL. If that works end-to-end, the bundle is doing its job; everything else is refinement.

Implementation Patterns

Declare the target in form XML, not in PHP. The bundle's whole value is moving this decision from code to the editor. Expect something close to:

<property name="landingPage" type="single_page_selection">
    <meta>
        <title lang="en">Landing page after submit</title>
        <title lang="de">Landingpage nach dem Absenden</title>
    </meta>
</property>

Confirm the exact type name from the README — some Sulu form property types are aliases of content types, and single_page_selection behaves differently from a plain text_line holding a URL. The former gives you a UUID you must resolve to a URL; the latter gives you a string but opens the door to editor typos and open redirects.

Resolve the target per request locale. Sulu page UUIDs are locale-agnostic, but URLs are not. In a multilingual site, resolve the URL with the current request's locale, not the admin's. If the bundle only stores a single UUID, your listener or a small decorator should do the StructureManager/route lookup with $request->getLocale().

Layer your own logic via event priority. The redirect should be the last thing that happens. If you need to push the submission to a CRM, write to a queue, or enrich data, subscribe to the same Sulu form-save event with a higher priority and let this bundle's listener run afterwards. Conversely, if mail delivery is synchronous and can throw, your listener should fail soft so the user still gets redirected rather than seeing a 500.

Handle AJAX frontends explicitly. A 302 on an XHR is followed transparently by the browser, so the user never leaves the page and your JS sees the thank-you HTML as a response body. Either submit the form as a normal POST, or detect X-Requested-With and have the bundle/your decorator return {"redirect": "..."} instead. Check whether the bundle already does this before writing your own.

Post-redirect analytics. The cleanest extension point is decorating the redirect listener (or its URL resolver) to append ?utm_source=form&utm_campaign=<form-key>. Do this in a decorator rather than editing vendor code, so composer update doesn't erase it.

Testing pattern that actually catches regressions:

$client->request('POST', '/contact', ['form' => [...valid data...]]);
$this->assertResponseRedirects($expectedThankYouUrl);

Add a second test for the failure path: invalid submission must not redirect but re-render with errors. That is the most common way these bundles break silently during upgrades — and a Symfony-major bump (as in 3.0.x) is exactly when request/response handling in a listener is most likely to shift.

Headless / API usage: if your form is consumed by a JSON endpoint, this bundle's HTTP redirect is the wrong contract. Read the submission event, extract the configured target yourself, and return it as a field in your JSON response — reusing the bundle for the editor UI while bypassing its response handling.

Gotchas and Tips

Treat adoption level as a risk signal, and treat the version jump as a bigger one. The line has moved from 0.x to 3.x with release notes that consist of "Update Symfony version" — meaning the major numbers are being spent on framework-constraint bumps, not on documented feature work. That is fine for a package this small, but it means: pin the version (composer require innomedio/sulu-form-landing-page-bundle:^3.0), read the composer.json require block to confirm your Symfony and Sulu majors, and read the ~100–300 lines of listener code before adopting. Honestly evaluate whether a hand-written event subscriber (roughly an afternoon's work) is cheaper than owning an unmaintained dependency. For a single redirect rule, it often is.

A Symfony-only patch release is still a deployment risk here. v3.0.1 touches nothing but the Symfony constraint, so the surface that can break is the same surface the listener lives on: the event dispatcher wiring, the request/response handling, and auto-wiring of the listener's constructor arguments. After upgrading, run the redirect integration test and the invalid-submission test before trusting it; if either fails, roll back rather than patching vendor code.

Bundle ordering matters. Register it after SuluFormBundle in config/bundles.php; event subscribers that depend on another bundle's dispatcher configuration can silently no-op otherwise.

Cache clearing is not optional. Sulu caches form metadata parsed from config/forms/*.xml. After adding the property, run bin/console cache:clear (or work in --env=dev) or the admin will not show the new field and you will spend twenty minutes convinced the bundle is broken.

Localization of the property itself. Sulu properties support <meta><title lang="..."> for labels, but the value is stored per locale only if the bundle declares it localizable. If editors need a different thank-you page per language, verify this in the source; if unsupported, store one UUID and resolve the localized URL at request time.

Unpublished or deleted target pages. An editor unpublishes the thank-you page and now every submission redirects to a 404. Guard the listener: if the target cannot be resolved to a live URL, fall back to a configured default route or the form's own success message. Do not let a stale UUID produce a broken redirect.

Open redirect / input validation. If the property is a free-text URL rather than a page selection, validate the host against your own domain before redirecting. This is the one security issue a bundle like this can realistically introduce.

Success flash messages get lost. The standard Sulu form flow sets a success message and re-renders. Switching to a redirect means that message no longer appears unless the listener flashes it to the session or the target page is configured to read a query parameter. Check both sides of the redirect before assuming the UX is complete.

Debugging checklist when no redirect happens:

bin/console debug:event-dispatcher | grep -i form
bin/console debug:container --tag=kernel.event_subscriber | grep -i landing

Confirm (a) the listener is registered, (b) the form key matches whatever filter the bundle applies, (c) the submission actually reached "saved" state (validation passed, mail didn't throw), and (d) your own controller isn't returning a Response that short-circuits the kernel's redirect handling.

Extension points to prefer, in order: decorate the redirect/URL-resolver service → add a config key via a compiler pass → override the listener service definition → fork. Only the last one carries real maintenance cost, and for a package this small, forking is a legitimate option — especially since each major release so far appears to be a constraint bump you could reproduce in your own subscriber in an afternoon.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log