Changelog β
All notable changes to FalconCMS are documented here.
Format follows Keep a Changelog β versions are sorted newest first.
v2.7.3 Latest β
Released: 2026-09-20
Fixed β
Updating from the dashboard could refuse to start, and staying that way was the CMS's own doing. Running
falcon:updatefrom a shell β on a Docker host, usually as root β leftvendor/falconcms/falconcmsowned by root. The site kept serving, because reading is all it needs, and the damage only showed at the next update, whose pre-flight check correctly stopped rather than let Composer half-replace the package. It told you tochownthe files, you did, and the next update from the command line undid it again. The command now hands ownership back to the user the site runs as β worked out from the owner ofpublic/index.php, not a guessed name β and only when it is actually running as root.A page a plugin's menu points at could not be opened by anyone but an administrator. The middleware works out which menu owns the path being requested and checks that menu's permission, but it looked in the menus table alone β and a menu registered with
falcon_add_menu_page()is not in it. So the menu appeared in the sidebar, its permission could be ticked in Roles, and opening it still answered 403. Registered menus and their submenus are matched now, and one declared'public' => trueopens for any signed-in user.Clicking Shop went to Orders instead of Overview. A migration corrected that route in June and the seeder put it back on the next update, because it truncates the menus table and rebuilds it every time β so the fix was undone by every
falcon:updatefor three months.Two columns were written and silently dropped. Eloquent discards a value for a column outside
$fillablewithout a word.menus.paramscarries thetype=productthat is the only thing telling Products β All Products apart from Posts; seeding kept it by accident, so sites looked right while any other code path lost it.cms_forms.lang_codewas passed on every form create and saved as nothing.
Changed β
- Nothing in the public API. This release is corrections to 2.7.2.
v2.7.2 β
Released: 2026-09-20
For theme and plugin developers
The helper functions and hook tags that still said lazy_ are now falcon_, and the stored settings keyed under the old name have moved with them. Nothing you have written stops working: every old helper name remains as a forward, every renamed hook fires for callbacks registered under either name, and a value saved under an old key is still read. Old [lazy_*] builder shortcodes still render. The new names are what the documentation teaches from here; the old ones are kept for code already in the wild.
Added β
A mega menu the theme header builds itself. Customizer β Menu β Mega Menu turns on a per-item checkbox under Appearance β Menus: a top-level item with sub-items can show them as a multi-column panel instead of a dropdown, with a column count up to six and a panel width of full, site, or one you name. Eight item-border styles β a rule under each item, a dashed one, a rule under each column heading, vertical rules between columns, a full table grid, and two that reveal on hover β each with its own colour at rest and on hover. Desktop only, and only for the theme's own header; the Layout builder is unaffected, and with the switch off nothing changes at all.
A custom post type can choose where it sits in the sidebar. ACPT β Post Types β Advanced Configuration β Menu Position lists every menu in the dashboard; the type appears directly below the one you pick and the choice is remembered.
The icon picker offers every icon the dashboard can draw β all 4,237 in the bundled icon font, read out of the font itself so nothing renders as an empty box, with a search box over the whole set.
Forms can be renamed. The builder's heading is the field: click it and type. The shortcode's
slugdeliberately does not follow, so pages the form is already on keep working.A child theme inherits its parent's templates.
make:theme --childsaid it did and it did not β a child holding no copy of a template fell through to the default theme rather than to the parent it was made from.The taxonomy archive bases are settings.
/category/β¦and/tag/β¦were written into the route file; they are on SEO Settings β Permalinks now, so a site can serve/topics/foodwithout editing the package and losing it on the next update.The loop can order by
published_at, and its paginator keeps the rest of the query string β a reader who searched and then turned the page no longer lands on the unfiltered list.Renaming a term leaves a redirect behind, the way renaming a page always has. A category slug is an address; editing it used to 404 every link to the old one.
Menus registered by a plugin or theme appear in Users β Roles.
falcon_add_menu_page()could put an entry in the sidebar that no administrator could grant to anybody, because the capability existed only in the package's source. They are listed now, under the same groups the sidebar uses. Two keys opt out:'public' => truefor something every signed-in user should reach, and'show_in_roles' => falsefor a capability granted elsewhere. A menu registered without a capability gets one of its own rather than borrowing the dashboard's.
Changed β
Shop and Products have a sidebar section of their own, headed eCommerce, the way ACPT heads Advanced.
A subscriber holds the Dashboard and its Overview, and nothing else. The role was seeded with
manage_users, which drew a Users entry in the sidebar of everyone who had just registered β and every page behind it answered 403. The customer role is narrowed the same way. A role an administrator has edited is left exactly as they set it.The Post Types and Taxonomies lists use the full width, like Field Groups beside them.
Fixed β
One unguarded mega-menu property took the whole header down. Every property but
mega_columnswas read defensively; a menu row saved before that column existed threw, and the header is on every page, so the site 500'd rather than one menu rendering plainly.Static page caching could serve one visitor's basket to another. The cache keys a finished page on its URL alone,
/cartand/checkoutsat inside that route group, and every page's header carries a basket count. Silent, because every response was a valid 200.Products sits under Shop again, and this time it stays there. A post type's menu position was computed from its database id β
40 + idon three code paths and60 + idon three others β so a type with the wrong id collided with Shop and the sidebar drew the tie in whichever order the database felt like. Nothing derives a position from an id any more.Analytics drew an empty chart on Today, its default range: a single day is a single data point, and a line through one point with no markers is nothing at all. Today is plotted by the hour now, in the site's own timezone.
An options page, its menu and its guard now name the same permission.
falcon_add_options_page()gave its menumanage_settingswhile the middleware guarded the page withmanage_options_<slug>and the Roles screen listed neither β so a role holding Settings saw the menu and got a 403 from clicking it.Role grants made under the old permission spelling are carried across. Two rules derived a menu's slug and disagreed about every child menu, so a permission could be granted that nothing ever checked. The migration only ever adds, never removes, and declines the handful of old names that two menus shared rather than guessing which was meant.
A term link follows the configured archive base, instead of the one written into the helper β which, on a site that had changed a base, sent every link the long way round through a redirect.
A menu item pointing at a category points at where that category lives now. The address was stored the day it was added; renaming the category left the menu on the old one.
Two menus may share a name. The slug was built straight from the name, so naming a second menu after an existing one put a duplicate-key stack trace on the screen.
Two forms with the same name no longer share a shortcode. The slug was made from the title without checking for a collision.
Product page scripts survive an out-of-stock product. The inline script bound a handler to an add-to-cart form that is not rendered when a product cannot be bought, and the throw took the description tabs down with it.
Two admin screens misdescribed a custom post type β the field-group location rule listed Post and Pages twice, once hard-coded and once from the table.
v2.7.1 β
Released: 2026-09-15
Added β
A custom post type can choose where it sits in the sidebar. ACPT β Post Types β Advanced Configuration β Menu Position lists every menu in the dashboard; the type appears directly below the one you pick, joining that menu's section. The choice is remembered, so re-saving the type does not quietly send it back to the bottom.
The icon picker offers every icon the dashboard can draw. The Icons tab had 36 hard-coded pictures. It now has all 4,237 icons the bundled icon font can actually render β read out of the font itself, so nothing in the grid can come out as an empty box β with a search box over the whole set. A post type saved with a custom SVG keeps it until someone picks something else.
Forms can be renamed. The name was set once, on the create screen, and there was no way back to it, so a form called "test" stayed that way. The builder's heading is the field now: click it and type, and it saves with the rest of the form. The shortcode's
slugdeliberately does not follow the name β it is what every[falcon_form slug="β¦"]already on a page points at, so a rename leaves those pages working.
Changed β
- Shop and Products have a sidebar section of their own, headed eCommerce, the way ACPT heads Advanced. Selling is a job of its own: a site that sells nothing reads the heading and skips both items.
Fixed β
Products sits under Shop again, and this time it stays there. A custom post type kept wedging itself between the two. The position of a post type's menu was computed from its database id β
40 + idon three code paths,60 + idon three others β so a type with the wrong id landed on the same number as Shop, and the sidebar drew the tie in whichever order the database felt like. Nothing derives a position from an id any more: a menu is inserted after a neighbour that is actually there, which keeps every position unique, and Shop and Products are treated as one block that cannot be opened. Existing sites are repaired on update.Analytics drew an empty chart on Today. Today is the default range, a single day is a single data point, and a line through one point with no markers is nothing at all β so the Traffic Overview card was blank however busy the site was. Today is plotted by the hour now, midnight to midnight in the site's own timezone, with the hours that have not happened yet left out so the line stops at the current hour instead of dropping to the floor.
Two forms with the same name no longer share a shortcode. The slug was made from the title without checking for a collision, so a second "Contact Form" got the same slug as the first and
[falcon_form slug="contact-form"]rendered whichever of the two the query happened to return first.The post and product editors said nothing when a save was refused. A failed validation redirects back with the reasons in the session, but neither editor printed them: the form came back filled in, nothing was saved, and the only clue was that the page had reloaded. A 150-character SKU went nowhere and said nothing. Both now show the list the page editor already did.
A variable product could not be published at all. The editor demanded a Regular Price for every product, and a variable product hides that field β each variation is priced β so Publish refused and pointed at a control nobody could see. Past that, the insert threw a 500 after the post row had already been written, leaving a product with no shop data priced at zero on the storefront. The parent now takes the cheapest variation's price, which is the figure the archive sorts and filters on, and the sale price follows only a discount on that variation. An empty variable product now says what is missing.
Per-variation weight and dimensions were lost when creating a product.
store()dropped whatupdate()kept, so a measurement typed while creating had to be typed again later.The last shipping zone and the last tax rate could not be deleted. Both are repeaters, and a repeater with nothing left in it posts no fields at all; the save read that as "this form carried no zones" and kept the old ones. They now carry the same marker coupons already had, so an empty list arrives as an empty list.
Media URLs were rewritten relative to the editor's own address, which broke the moment the same content was viewed anywhere else. The editors keep the URLs the library hands them.
A closed coupon took as much height as an open form row β a 40px circle, a badge stacked above an 18px code, six units of air between cards. It is one line of information, so it now takes one line.
v2.7.0 β
Released: 2026-09-08
Added β
Custom column widths. Column and Nested Column β Design β Use Custom Width opens a slider for any width the preset fractions cannot express. The presets and the slider are the same setting, so only one is shown at a time, and going back picks the nearest preset rather than leaving the row with nothing selected. Per device, like the presets β a column can be 1/3 on desktop and 45% on mobile.
A Today range on Analytics, and it is now the default. The question that page is opened to answer is almost always "what is happening now"; a week's total is the wrong shape for it. The other ranges are unchanged and still one click away.
Landing-page menus follow the reader. A menu built from
#pricing-style links now marks the item whose section is at the top of the viewport, scrolls smoothly when one is clicked, and stops short of a sticky header instead of leaving the heading underneath it. Both the theme header and the Layout builder's Menu element.Hover Border and Hover Animation on the Button element. The border gains a hover width per edge and a hover colour, kept directly under the border they change β blank keeps the resting value, and
0is a real answer. The animation offers Lift Up, Sink Down, Grow, Shrink, Glow and Pulse, and none of them for a reader whose system asks for reduced motion.
Changed β
Analytics counts a visitor once a day, and again the next day. Counting distinct addresses across a whole range had fixed one fault and introduced its opposite: someone who came back on ten different days was still one address, so a month looked no busier than a day. Every figure now counts distinct (address, day) pairs, so the cards agree with each other. Over Today it is the same number it always was β which is why this only ever showed on the longer ranges.
Longer ranges will therefore read higher than before on the same data. That is the correction, not a new fault.
New vs Returning is answered across the range. The old query only asked whether an address had been seen before the range began, so a reader who first arrived on Monday and came back every day counted as new all week. Their first day is new, the rest are returns, and the two still add up to the headline.
Active Pages lists every page the people here now have read, not only the page each of them is on at this instant. Each row counts people, so re-reading a page never counts twice.
Alignment on a full-width Button moves its label. A Full Width button already fills its row, so there was nowhere for Alignment to move it and the control looked broken. It now sets the text alignment inside the button. A button sized to its label is still placed within the row exactly as before.
Fixed β
Importing layouts failed with a database error on any site that had ever deleted a header or footer.
postsis unique on (slug, type, lang_code), but the import matched only slug and type and did so through the soft-delete scope β so a section in the bin was invisible to the check while still holding its key, and the insert was refused. The full key is matched now, a section in the bin is restored and reused, and a section that still cannot be placed is reported and skipped rather than taking the whole import down.Every custom link in a menu was marked as the current page. An item saved as
#pricinghas no path of its own, and reading that as/made all of them match on the home page. The theme header and the builder's Menu element also answered the question separately and disagreed with each other; they now share one answer.The unsaved-changes warning appeared when you pressed Save. Most of the admin saves by calling
form.submit()from script, which fires no submit event β so the guard never saw the save and asked Leave site? at the exact moment the work was being written. It still warns when a tab with unsaved edits is closed, which is all it was ever for.A Button's border could be invisible. Border Color was the only colour field in the panel that hid its opacity, so a border stored at 4% read as
#aaaand drew nothing β and the canvas ignored opacity altogether, showing a solid border for one the site would not draw. Section borders had the same fault on the canvas.Menu hover settings describe the current item too β border and border colour, as text and background already did.
The builder canvas and the site now draw a menu identically. Five properties were computed differently on each side, a cleared number field was handled differently, the canvas link inherited the
line-height: 0the editor puts on every element wrapper, and the editor's own padding and dashed border pushed the menu 5px in from where the site draws it.
v2.6.16 β
Released: 2026-09-08
Fixed β
- Changing the navigation font under Typography β Navigation had stopped working. v2.6.15 gave the Menu section its own Navigation Font Size and Font Weight; to have any effect those had to out-specify the typography rule, and doing so silenced it. Both Menu fields are gone again and Typography β Navigation is once more the single place the navigation font is set. Menu keeps what typography does not own: text colour, hover colour, item padding and the dropdown colours.
v2.6.15 β
Released: 2026-09-08
Fixed β
- Navigation Font Size and Font Weight work. v2.6.14 removed them instead of repairing them; both are back and applied. (Superseded by v2.6.16, which moved the navigation font to Typography β Navigation for good.)
- Dropdown Text Color reaches the mobile menu's sub-items, which were painted a fixed grey.
v2.6.14 β
Released: 2026-09-08
Fixed β
- The Customizer's Menu settings did not reach the theme header. Navigation Text Color was emitted only once a Navigation typography had also been saved, so on most sites it had no rule at all; Menu Item Padding could not do anything because the navigation carried a fixed 32px gap; and the mobile menu was painted with hard-coded classes, so every one of these settings stopped at the desktop breakpoint. Defaults are unchanged, so a site that never opened these controls looks the same.
- A layout slot switch asks for a state instead of a flip. A double-click, a retried request or a tab opened before the slot changed elsewhere could land on the opposite value β read as "I switched it on, reloaded, and it was off".
- Falcon Builder β Sections could fail with
Undefined variable $errors, taking the whole page down with a 500.
v2.6.13 β
Released: 2026-09-07
Fixed β
A browser that has signed in before is no longer met by the 404. Since v2.6.7
/adminanswers a visitor without a session with a 404, so that guessing the obvious path cannot reveal where the login page was moved to. That is right for a stranger and wrong for the site's own administrator: sessions last hours, work in a builder tab lasts longer, and nothing on the site links back to a login page they may never have written down. A bare 404 at that moment reads as a broken site rather than "sign in again".A browser that has completed a sign-in here is now sent to the login page instead, with Your session has ended. Please sign in again. It already knows the address, so it learns nothing it did not have; a browser that has never signed in still gets the 404.
The marker is an ordinary Laravel cookie β encrypted and signed with
APP_KEY, so it cannot be produced by anyone without the key β and it only changes what an unauthenticated visitor is shown. It never signs anyone in.On a shared computer it does mean the next person to open
/adminreaches the login page. Signing out does not remove it, on purpose: after signing out deliberately, the next visit should still find the way back in.Three pages sent new installs to the wrong address. The installation guide, the introduction and the home page all still said to visit
/adminafter installing β which, since v2.6.7, answers 404 and looks exactly like a failed installation. They now name the login URL the installer prints (/falcon-adminon a fresh install).
v2.6.12 β
Released: 2026-09-06
Fixed β
The per-minute graph in the Real-Time panel counted page views. It was the last figure on the analytics page still counting rows, so one person opening four pages inside a minute drew a bar four times too tall β beside a counter that correctly said one visitor.
It counts distinct visitors per minute now, like everything else on the page, and the caption says Visitors per minute rather than Visits.
v2.6.11 β
Released: 2026-09-06
Changed β
Analytics counts people, everywhere. One visitor is one visitor, however many pages they open. That rule now holds across the whole page rather than in the few places it already did.
Visitors, Visitors Today, Visitors This Month, the period-over-period change, Top Pages, Top Referrers, Traffic Channels, Traffic Sources and the Browser / Device / Operating System breakdowns all counted rows β one row per page view β so somebody reading four pages arrived as four. All of them count distinct visitors now, by IP address, which is the basis Unique Visitors always used.
Page views have not been thrown away, because "how much was read" is a real question: the second tile is now Page Views, and the traffic graph still plots page views against visitors. It previously repeated the Unique Visitors figure, which became a duplicate of the headline once that started counting people.
Tiles are named for what they hold β Visitors, Page Views, Visitors Today, Visitors This Month β so no figure claims to be people while counting pages.
Which pages, referrers and sources appear is unchanged. Only the multiplied people are gone.
v2.6.10 β
Released: 2026-09-06
Fixed β
The Real-Time panel put one visitor on every page they had read. It said "1 active user right now" while the table beneath it listed six pages with one user each β the same person, placed on all six at once, reading as six people.
A visitor is in one place at a time, so the panel is now built from one row per visitor: their most recent page view. Each person is counted once, on the page they are actually on, and the headline count and the table are derived from the same rows β so the column always adds up to the number beside the dot. Which pages are listed is unchanged; only the double-counted people are gone.
This completes what v2.6.9 started: that release stopped a page being counted twice for one person, but still listed that person on every page they had passed through.
created_aton analytics rows compared as text, not as a moment, because the model disables timestamps and never cast it. Anything filtering those rows in PHP rather than SQL was comparing strings.
v2.6.9 β
Released: 2026-09-06
Fixed β
Analytics counted one person as many. Every card is fed from one row per page view, and four of them counted rows where they meant people: Visitors by Country, Top Countries, Active Pages, and the Live Visitors list β which showed the latest eight rows, so somebody reading eight pages filled it on their own and read as eight separate visitors from eight places.
Those four now count distinct visitors. Nothing was slightly off: each figure was multiplied by however much each person happened to read, which is precisely the number a site owner uses to judge whether anything is working. Unique Visitors, New vs Returning and the live "active now" count were already right.
Visits stay a count of page views, because that is a different and equally real question β Top Pages, Recent Visits and the traffic graph are unchanged.
A settings change could appear not to save at all. When the shared settings cache cannot be invalidated, the write lands in the database but every later request keeps reading the old value, so the setting silently reverts on the next page load β and starts working an hour later when the cache expires on its own. That failure was being swallowed. It is now logged, naming the usual cause: a cache file left owned by another user, which is what happens the moment anyone runs
php artisanas root over SSH on a site that runs aswww-data.If settings seem not to stick, check
storage/framework/cacheownership β and prefer running artisan as the web user.The real-time analytics feed could not run on SQLite, because its per-minute grouping used a MySQL-only date function while the rest of the page had already been written for both.
v2.6.8 β
Released: 2026-09-06
Fixed β
A site with an active plugin returned 500 on every front-end page after updating to v2.6.7. Plugins moved into
resources/views/pluginsin that release, and a security check that only allows a view underresources/viewsto render if it sits inthemes/orvendor/had not been told about the new location β so the first plugin view a page rendered aborted the request mid-layout.It never showed up in development because that check quietly disables itself on a site with no
resources/views/vendordirectory:realpath()returnsfalsefor a directory that is not there, and PHP compares thatfalseagainst'', which every path starts with. A site that has published views β which is any site that has been updated β had the check switched on and went down. Plugin views are now allowed explicitly, and the tests around it create that directory so this cannot pass unnoticed again.Turning a layout slot off did nothing, and came back on after a reload. In Falcon Builder β Sections, the switch for a slot with no section assigned to it reported success and drew itself off, but there was nothing to store, so the next page load showed it on again. The endpoint could not tell "nothing is assigned here" from "it is now off" β both were the same
false. It now says which, so the switch stays honest, and a slot that has a section assigned toggles and persists as it always should have.
v2.6.7 β
Released: 2026-09-06
Security β
/adminno longer gives away the login page. The login URL can be moved off a guessable path in Settings, but any anonymous request to/adminwas answered with a redirect to wherever it had been moved to β and/admin/loginredirected there too. The one address an attacker is guaranteed to try was handing over the one address the setting exists to hide. To a visitor without a session the admin now simply returns 404.A signed-in administrator sees no change. The trade-off is that a session which expires mid-edit now ends in a 404 rather than the login form, so keep the login URL somewhere you can find it.
The wishlist no longer leaks the admin login URL either. Its "please log in" reply carried
route('admin.login')β in JSON, to every anonymous visitor who clicked the heart. Shoppers sign in on the storefront account page, so that is where the wishlist now points, and it passesredirect_toso they come back to their wishlist afterwards instead of being stranded on the account page.
Added β
A warning before you lose unsaved work. Close the tab or navigate away with changes you have not saved and the browser asks first. It covers the page builder, where it follows the same state the Save button does, and every admin screen β post, page, product, settings β through the shared layout.
Deliberately quiet: only POST forms count, so typing in a search box never triggers it; only real typing counts, not values scripts set while the page loads; submitting clears it; and rich-text editors are asked directly whether they are dirty, since they type inside their own frame where those events never reach.
Nested columns are edited in place, and closed when you are done. A nested row now draws closed, with the same edit/add panel a container or column carries sitting on it. The pencil opens it; a Finished tick closes it again. While it is open the rest of the canvas dims and stops responding, so a click meant for the nested column cannot land in the section behind it, and no new container or column can be started on top of half finished work. Save arms when you finish, not on every keystroke inside.
Closing puts the editing chrome away, never the design: a row with content in it keeps showing that content, and only an empty one falls back to a placeholder bar. Preview mode ignores all of it and draws the real page.
Fixed β
The Card element ignored its Layout setting on the canvas. Grid, List, Masonry and Carousel all render through a stylesheet the element emits, and the builder sanitises the preview HTML before inserting it β which dropped that stylesheet on the floor. Every layout therefore looked identical while the front-end rendered them correctly. The CSS is now lifted out before sanitising and mounted as the preview's own stylesheet, so the canvas changes the moment you switch layout.
The Falcon Slider element showed nothing once a slider was chosen. Same cause, one step further: the live preview is an
<iframe>, and the sanitiser removes those outright, so the canvas was left with an empty box. The preview frame is now rendered as a real element rather than passed through as markup.A menu item that is only an anchor broke the header on PHP 8.1+.
#sectionhas no path forparse_url()to return, and the result went straight intoltrim()β a deprecation notice on every page with such an item. Along the way the active-state check learned three things it had never known: the Home item now highlights on the home page, a menu URL written with a trailing slash matches the page it points at, and a link to another site can no longer light up as the current page.
Changed β
- Plugins live in
resources/views/plugins, alongside themes, instead of aplugins/directory at the project root.php artisan falcon:updatemoves an existing install across β keeping each plugin's active state, data and migrations β and until it runs the old location keeps working, so updating the package on its own breaks nothing. Nothing at the destination is ever overwritten: a name that already exists there is left alone and reported.
v2.6.6 β
Released: 2026-09-06
Added β
Callout element Pro. The boxed aside that documentation runs on β note, tip, success, warning, danger and four more β in nine variants and six presets, from a plain accent bar to a solid header. It can be made collapsible, and when it is it uses a real
<details>: it opens with the keyboard, and a browser's find-in-page opens it to show a match rather than reporting nothing. The body takes the same small markup the Table's cells do, so a callout can hold a bulleted list,`code`, a link or a button, and it holds text rather than HTML, so one can never carry a script.Table of Contents element Pro. It reads the headings out of the page itself, so nothing has to be listed by hand and nothing goes stale when a section is renamed. Choose which levels to include, five presets, optional numbering, collapse by default, and a sticky mode that follows the reader down the page. The entry for the section being read is highlighted as it scrolls, and can carry its own background colour.
Anchors are built from the heading text, including scripts whose letters carry combining marks β Bengali headings get real anchors rather than a string of dashes.
Previous / Next element Pro. Links to the pages either side of this one, ordered by a navigation menu or by date, with either side overridable by hand. It stays inactive on a page that has no Table of Contents, because "previous" and "next" only mean something inside a sequence a reader is actually following.
A button in a table cell.
[button Buy now](/pricing), with:primary,:ghostand:softvariants β the missing half of a pricing or comparison table, which otherwise ends in a row of plain links.Image Lightbox, in the Image element's General tab. The image opens full size on click, using the Gallery's lightbox rather than a second one. Turning it on puts the Link URL field away, and the page ignores any URL already saved there β an image that quietly went on navigating would look like the lightbox was broken.
Back to Top button, in Customizer β Performance. On by default, with twelve settings: how far down the page it appears, which corner, size, corner radius, three icons, its own colours, an optional reading-progress ring and an option to hide it on phones. Turning it off sends nothing to the page at all β no markup, no stylesheet, no script.
Text Animation, in the Extra tab of the Title, Text Block, Button and Callout. Sixteen looping animations in three groups β motion, emphasis, and light and colour β with the speed, delay, repeat count, easing and accent colour all adjustable, and a default speed per animation rather than one speed for all of them. It is distinct from the Scroll Entrance Animation beside it, which plays once on arrival; the two can be used together.
Drag anywhere in the navigator. The tree lets a node be moved across branches now β an element from one column to another, a column into a different container, an element in or out of a nested column. A drop that would do nothing, or that would put a node inside itself, is refused rather than silently ignored.
Paste wherever the clipboard can land. What a copied node is now decides where it can go, rather than where it happened to be right-clicked. An element copied from a plain column goes into a nested one and back; a container can be pasted onto the bare canvas of a page that has nothing on it yet. The menu says what will land where, or why it cannot.
Changed β
- Email verification is off on a new install. A fresh install can be logged into straight away instead of waiting on a verification email from a site that has not been given a mail server yet. Turning it on afterwards works as it always did; existing sites are untouched.
Fixed β
Letter spacing did nothing, anywhere. A bare number reached the stylesheet as
letter-spacing: 2, which is not a length, so the declaration was dropped β the control had never worked on any element, the Table included since v2.6.4. Units for the shared typography controls now live in one place, so line height keeps being unitless while sizes and spacing get theirpx.A quotation mark in any text setting truncated it. A caption reading
He said "hi"was cut off at the first quote when saved. This was in the shortcode converter itself, so it affected every element with a text field, not one of them.The Gallery and Image lightboxes did not cover the screen. A
position: fixedoverlay is only fixed to the viewport while no ancestor has a transform, a filter or awill-changeβ any of those makes that ancestor the containing block instead. The builder's own entrance animations set one on a wrapper around every animated element, so an image inside one opened into an overlay the size of its own column: the backdrop covered a corner of the page and the picture spilled out of it. Measured on a real page, 593px wide inside a 1200px window.Maintenance mode did not hide the site. The check for who may still see it asked for a permission that is not a staff signal, and on a site whose subscriber role holds it, that was everyone. It asks whether the visitor is an administrator now, and admins browsing the site are shown a bar telling them maintenance mode is on, so it cannot be left running unnoticed.
The Heading element's settings panel was empty. Both tabs. It now has the content and design settings every other element has, and can be set to full width.
Anchor links now keep the trailing slash, so a link to a section reads
/page/#sectionrather than/page#section. This covers every place a menu is drawn β the builder's Menu element, the navigation widget, and the theme's header, dropdowns and footer.The Table of Contents entry being read is tracked by position rather than by an intersection band, which highlighted the second heading at the top of a page, never followed a click, and went blank in the middle of a long section. Its sticky mode works now too: it is applied to the column rather than to the element, which cannot travel outside its own box.
Callout lists render the same in the editor and on the page. The admin's stylesheet strips list markers and paragraph margins from everything, so bullets previewed flat and then arrived bulleted. Both renderers now load the same rules.
The Callout's icon is chosen from the icon picker rather than typed in as a class name.
Internal β
- Eleven new test files, and 147 more tests than v2.6.5 β 718 in all. Among them, the builder's inline script is now parsed by node on every run, and the parts of it that decide where a drag or a paste can land are lifted out and run against a real layout, which is coverage nothing in the suite had before: PHPStan does not read Blade templates, so none of that code was seen by anything until now.
v2.6.5 β
Released: 2026-09-04
Fixed β
The page builder returned a 500 on servers with
short_open_tagenabled. The Code Block element added in v2.6.4 ships a sample snippet, and the sample was PHP, so the builder's script file contained the characters that open a PHP tag. Blade compiles a template by running PHP's tokenizer over it, so on a server where a bare<?opens code, everything below that point was handed back as PHP and passed through without being compiled β and the builder died withunexpected identifier "App"before drawing anything. Sites where the setting is off, which includes every development machine we build on, were never affected.The snippet is now joined at runtime, and the test that has guarded against this since v2.6.3 no longer only reads the templates: it compiles every one of them with the setting on and checks the result parses. That is the check that would have caught this, and it would equally have caught the sitemap fault behind v2.6.3.
v2.6.4 β
Released: 2026-09-04
Added β
Table element Pro. A real table in the page builder, with six presets, per-column alignment and width, an optional header row and header column, a caption, sticky headers and a max height. Readers can sort by clicking a header β numbers and versions sort as values, so
10does not land before9, norv2.10.0beforev2.9.0. On phones a wide table either scrolls or turns each row into a card carrying its column names, because side-scrolling hides the first column, the one that says what the row is about.Cells take a small markup β
`code`,**bold**,*italic*,[text](url),<br>β and[check],[cross]or[icon fas fa-star]for icons, which is what a comparison or pricing table is mostly made of. Cells hold text, never HTML, so one can never carry a script.Paste a Markdown table and it imports, alignment row and all, along with CSV and a spreadsheet paste, which is the difference between adopting the element and retyping a documentation site by hand. Rows and columns can be picked out with their own colour, and the header and body each take the same typography controls as every other element.
Code Block element Pro. Syntax highlighting for thirteen languages in five colour themes, with line numbers, highlighted lines, a window bar with the file name, word wrap and a max height. A copy button puts the original source on the clipboard rather than the numbered lines beside it, and says so when a browser refuses to copy instead of sitting there looking dead.
Highlighting happens on the server, so a visitor with JavaScript off still gets a coloured, selectable block. Two reveals are available on top of the builder's own entrance animations: a typewriter that types the snippet out character by character, and a line-by-line fade. Both stand aside for
prefers-reduced-motion.Head HTML in Appearance β Customize β Custom Scripts. The two existing script fields take JavaScript and are wrapped in a
<script>tag, which left nowhere to put the things a site needs in its head that are not script: a Search Console or Facebook verification<meta>, a<link>, or a loader that arrives as<script src="β¦">β which is how Google Tag Manager, Meta Pixel and Lemon Squeezy are all published. Sites had to edit a theme file, and the next update overwrote it.
Fixed β
DOMPurify was missing from the package. The builder loads it and guards against its absence, so nothing ever appeared broken β it simply fell back to unguarded
innerHTML, which means client-side sanitising in the canvas has never actually run, on any site. The library is now shipped, and reaches existing sites on the next update.Changing the login or registration URL did nothing on a live site. Both slugs are read while routes are being registered, and a site with cached routes never runs that file β so the setting saved, the new URL returned 404 and the old one carried on working, with nothing to say a cache was in the way. Every production install caches its routes, so this affected all of them. Saving either slug now rebuilds the route cache, and a site without one is left alone.
v2.6.3 β
Released: 2026-09-04
Fixed β
- The sitemap returned a 500 on any server with
short_open_tagenabled. Blade does not read a template as plain text β it runstoken_get_all()over the source and applies its directives only to the inline-HTML tokens that come back. Whereshort_open_tagis On, PHP's tokenizer treats the<?that opens an XML declaration as the start of PHP code, so the rest of the template was handed back as PHP tokens and written to the compiled view uncompiled. Visitors got a parse error instead of a sitemap. The declaration is now assembled from pieces so those two characters never sit together in the file. The template renders identically either way; only servers withshort_open_tag=Onwere affected, which is why it never appeared in local development. - A guard now scans every Blade template in the package for the same hazard, so no future template can be served uncompiled on those servers.
v2.6.2 β
Released: 2026-09-03
Fixed β
- The sitemap returned a 500 for the whole site when it met a post with no timestamps.
lastmodwas written unconditionally, soupdated_atbeing null ended the response β and with it every URL in the file. Content that arrives through the WordPress importer, a seeder, or a raw insert can have no timestamps at all.lastmodis optional in the sitemap spec, so it is now emitted only when there is a date, falling back tocreated_atbefore being left out entirely. Nobody sees this failure while it is happening β it is fetched by search engines, not people β so the site simply stops being crawled. - A post with an empty slug no longer appears in the sitemap. Its
<loc>resolved to the site root, so the home page was listed once more for every such row. - The category and tag sections are skipped when a site has removed those archive routes, rather than failing to generate a URL for a route that is not there.
- The sitemap query now selects only the columns the file actually uses, instead of hydrating every column of every published post on the site.
v2.6.1 β
Released: 2026-09-01
Added β
- Section Separator element. A divider you can drop into any column, with 61 styles in three families: 8 CSS line styles, 15 repeating SVG patterns, and 37 full-width shape dividers (waves, hills, clouds, mountains, grass, arches, aurora and more). Text or an icon can sit on the line, positioned left, centre or right. Shapes take a height, can be flipped horizontally or inverted, and layered shapes carry their own opacities.
- Custom SVG shapes. Pick an SVG from the media library and its artwork is inlined on the element, so the separator colour, height and flip reach it. The markup is sanitised on the way in and again on render.
- SVG uploads are now a site decision. SVG was refused outright before, even though Customizer -> Performance -> Allowed Upload Formats offered it. It is now governed by that setting, is off unless a site names it explicitly, and whatever is kept has been rewritten through the sanitiser first, so an SVG in the library cannot carry a script, an event handler or a
javascript:link. The same rule applies to a backup restore.
Fixed β
- The builder canvas added height a published page never had. Blade partials that began with a UTF-8 byte-order mark emitted it into the page; a BOM is not whitespace, so each one formed a text line inside the element wrapper. A nested row was pushed about 24px down its column and the column's background showed as a band above it, with every padding set to 0. The mark is gone from 29 templates, and the wrapper is now a flex container so stray whitespace cannot do the same again.
- A column's hover effect (Lift, Zoom, Glow, Fade) was applied to the outer box while the card's background, radius and padding live on the inner one. The lift shadow was drawn square around a rounded card, and hovering the empty area beside the card still triggered it.
- A nested row carried a 1px transparent border and a
flex-basis: 100%that, in a column-direction flex parent, asked it to be as tall as the whole column.
v2.6.0 β
Released: 2026-08-28
Changed β
- Requirements are now Laravel 13+ and PHP 8.3+. The package previously declared support for Laravel 10, 11 and 12 and PHP 8.1, but only Laravel 13 was ever exercised by the test suite. The Composer constraints, the CI matrix and the documentation now all state the versions FalconCMS is actually built and tested against. Existing sites on an older Laravel are not broken β Composer simply keeps them on the last release that matched their framework.
- The CI test and syntax matrices run on PHP 8.3 and 8.4, and
orchestra/testbenchis pinned to^11.0, the release line that targets Laravel 13.
Fixed β
- Every documentation page rendered a literal
%sin its browser title (for exampleInstallation | %s | FalconCMS). The site'stitleTemplateused printf syntax instead of VitePress's:titleplaceholder.
Documentation β
- The documentation homepage now links into the docs from every feature card, and adds sections covering installation, custom post types, the builder, e-commerce, plugins, the hook API, requirements and a grouped documentation map.
- Added a Plugins feature card, a Live Demo call to action, and a card-based "Explore the Documentation" link map.
- Added page metadata across the site β canonical URLs, Open Graph and Twitter tags, and
SoftwareApplication/WebSitestructured data on the homepage. - Enlarged the homepage hero image and reduced the hero heading size.
v2.5.0 β
Released: 2026-08-28
Added β
- Column Order field β rearrange a column, or a nested column, visually per breakpoint from the General tab. Desktop, Tablet and Mobile can each have their own order without moving the column in the document, so tab order and screen readers are unaffected.
- Full icon library in Menu Item Options β the icon picker for menu items now offers every icon the builder ships (Font Awesome, Bootstrap, Remix, Boxicons, Lucide β ~10,000 icons) instead of a curated subset of about a hundred, with paging so the grid stays fast.
Fixed β
- The builder canvas could render a menu's text in the wrong font β both a broken Google Fonts request for a custom font, and reading the theme's body font instead of its Navigation font for "Inherit".
- Desktop preview in the canvas could be narrower than a real desktop, so content spilled past its own column; the canvas now matches the theme's real desktop breakpoint.
- Cart / Search / Wishlist menu items ignored a custom icon chosen for them, and the count badge ignored the Customizer's Primary Color.
v2.4.0 β
Released: 2026-08-12
Added β
- Shop archive filters β a sidebar with product search (title, excerpt and SKU), a dual-handle price range slider, categories, attributes, In stock only and On sale. Filtering happens over AJAX and rewrites the address bar, so a filtered view is a real shareable URL and the back button behaves. With JavaScript switched off the panel is a plain GET form and every filter still works.
- Attribute filters β whatever attributes your products declare appear in the sidebar automatically, with counts. Each attribute gains a Show in filters switch next to Visible on the product page, so a noisy attribute can be kept out of the sidebar while still showing on the product page.
- "Visible on the product page" now does something β ticked attributes appear in the Additional information table. The setting was previously stored but never read.
- Weight-based shipping β shipping zones gain a Weight Based (Per Weight Range) calculation type, banded exactly like the quantity rates. Product weights finally feed into the shipping cost.
- Customer address book β customers save addresses under My Account β Addresses, with separate defaults for billing and shipping. Checkout is pre-filled server-side, and a picker appears when more than one address is saved.
- Upsells and cross-sells β chosen per product in a new Linked Products tab. Upsells show on the product page, cross-sells in the cart. Related products are now drawn from the product's category instead of "the four newest products in the shop".
- Product structured data β product pages emit schema.org JSON-LD:
Offerfor simple products,AggregateOfferfor variable ones, plus availability and star ratings. This is what puts price and stock into a Google result. falcon:reindex-attributesβ rebuilds the attribute filter index. Only needed after a bulk import or a direct database edit; ordinary saves keep it current.
Fixed β
- Cart prices are re-read from the catalogue on every cart, checkout and order. They used to be frozen at the moment an item went in, so an ended sale β or a price the shop owner had since corrected β never reached a basket that already existed.
- An expired sale stops applying the moment it ends, rather than whenever
falcon:expire-salesnext runs. The stored sale price is left untouched, so the figure is still there when the shop owner extends the sale. - Variable products report stock from their variations. Selling the last of every size no longer leaves the product advertising itself as in stock. The In stock only filter follows the same rule, so the badge and the filter cannot disagree.
- Variable products show a price range (
ΰ§³1,500 β ΰ§³2,500) instead of the parent row's0.00. - The shop grid applies the tax display conversion. With prices entered without tax and displayed with it, a product used to cost one thing on the shop page and another on its own page.
- Product type is no longer split across two columns.
shop_products.typeand.product_typehad drifted apart β the editor only wrote one of them β so a product could read as variable on the storefront and simple in the admin. Both are written now and a migration reconciles existing rows. - "Enable tax rates and calculations" could not be ticked from the General tab: the same field was posted twice by one form and the Tax tab's hidden value won.
- Unchecking "Show in filters" now sticks. An unchecked box submits nothing, and the stored
'0'reads as truthy in JavaScript. - Shop sits directly under Products in the admin menu, and custom post types are numbered above the pair so a new one cannot come between them.
- Cart layout: Update cart keeps its place when coupons are switched off, and the cart and checkout buttons share one hover treatment.
Upgrading β
Run php artisan migrate after updating. Ten migrations ship with this release; eight only add tables or columns. Two adjust existing rows β the product type reconcile and the admin menu order β and both are reversible. Nothing is demoted: a product that was being treated as variable stays variable.
v2.3.0 β
Released: 2026-08-05
Added β
- Content Box element β a repeater element with eight layouts: Classic Icon With Title, Classic Icon On Top, Classic Icon On Side, Classic Icon Boxed, Clean Layout Vertical, Clean Layout Horizontal, Timeline Vertical and Timeline Horizontal. Each box carries its own icon (or image), title, rich content, background and Read More link; the element adds column count, alignment, link type (text or button), link area (the Read More link or the whole box), and full typography, box and timeline-rail styling. Layouts collapse to two columns on tablet and one on mobile.
- Four more icon libraries β Bootstrap Icons, Remix Icon, Boxicons and Lucide join Font Awesome, taking the picker from 2,060 to 10,115 icons. They cost nothing until used: the builder fetches a library's icon list and stylesheet only when its tab is opened, and a page loads a library's stylesheet only when that page actually contains one of its icons.
- Font Awesome icons are findable by their older names. Font Awesome keeps every previous name working as an alias of the current one, but the picker only listed current names β so searching "ambulance", "trash-alt" or "shopping-cart" found nothing even though the icon was right there. 1,102 alias names are now searchable, read from the shipped stylesheet.
- Taxonomy dynamic sources. A new Taxonomy text source prints a post's terms β pick a post type, then one of its taxonomies, with separator, term limit and fallback β and a matching Taxonomy URL link source points an element at the term's archive. The post type and taxonomy must both match, so one template can be reused across post types safely.
- Icon Box β Read More typography. The Read More link now has its own font family, size, weight, line height, letter spacing, transform, colour, hover colour, arrow toggle, and controls for its distance from the description and the gap before its arrow.
Fixed β
- Every font picker in the builder is searchable. Icon Box, Accordion, Tabs, Ticker, Post Meta and every ACPT custom field still used a plain dropdown of ~1,700 fonts; they now use the same searchable picker as the Title element.
- Front-end now loads every font the builder can choose. Font collection ran off a hard-coded list of setting keys, so fonts picked for Read More, sub/mobile menus, Post Meta and custom fields were never loaded and silently fell back to the theme font. Detection is now by key name and walks nested layouts, header/footer sections are included, the full 100β900 weight range is requested (Thin and Extra Light used to be missing), and families the bundled catalog doesn't know are dropped β one unknown family made Google reject the whole request, which had been taking every font on the page down with it.
- Post Meta no longer 500s a page. Placed directly on a page or post, the element hit an undefined
$postand Blade's error handling reported it as "Cannot end a section without first starting one", which pointed nowhere near the cause. - Hover colours are visible in the builder again. Icon Box's Read More hover colour and Breadcrumb's link hover colour rendered on the front-end but looked dead in the canvas, since an inline style can't express
:hover. - Element panels always open on their first tab. After working in one element's Design tab, the next element you opened β a duplicate most visibly β also opened on Design.
- The icon picker's search box no longer carries over. A query typed for one element used to filter the icon grid of the next element you opened.
- Boxes with a background or border get room inside them. Content Box items whose padding was never set sat flush against their own border, with the icon and Read More link crossing it.
v2.2.7 β
Released: 2026-08-04
Fixed β
- Pro builder options no longer show as locked on a licensed site. The builder's Pro-edit flag was set only by the page/section builder screen, so the Post Card builder and Mega Menu builder β which share the same builder scripts β read it as missing and locked every Pro element (accordion, tabs, counter, gallery, ticker, breadcrumb, star rating, HTML, card, icon box, icon list, menu, advanced search), dynamic content and global sections even with a valid license. The flag now lives in the shared builder partial, so every builder screen answers from the license.
- Card element now fills its column on the front-end. A column's inner box is a column-direction flex container whose default content alignment is
flex-start, so the card element was sized to fit-content: the cards collapsed to their text width and the row left dead space on the right β while the builder canvas (which wraps the same markup in a full-width div) looked correct. The card element now stretches to the column like every other layout block, for grid, list, masonry and carousel alike.
v2.2.6 β
Released: 2026-08-01
Changed β
- Pro is a one-time, perpetual license. Paid Pro features never expire β a purchase is owned forever. A license's expiry now only limits updates: when the update window ends, the site keeps every Pro feature and simply needs a renewal to pull newer Pro releases. Refunded/disabled licenses still revoke access. The free core (including e-commerce) stays free for everyone, always β licensing never touches it.
- The License and Updates pages now show "Update window ended β features stay active, renew for updates" instead of looking locked out, and the Pro update button is gated by the update window rather than by raw license validity.
v2.2.5 β
Released: 2026-07-31
Added β
- Icon Box β Read More link. A Read More / Learn More link can now be shown under the description (text + URL), rendered only when set.
- Icon Box β Link Mode. Choose what the link applies to: Full Box, Only Icon, or Only Title. Defaults to Full Box, so existing icon boxes are unchanged.
Fixed β
- Counter animation no longer disappears. The count-up script is now emitted with every Counter and self-dedupes in JavaScript, instead of being gated by a render-once guard that a hidden/earlier render pass (Layout Builder sections, meta/excerpt, nested renders) could consume β which stripped the script from the visible page and left the number static.
- Pro update stops cleanly on read-only vendor files. The Pro updater's pre-flight check now also verifies
vendor/falconcms/prois writable, so a containerised install with a root-owned vendor tree aborts up front (with the exactchownfix) instead of letting Composer half-modifycomposer.jsonmid-update.
v2.2.4 β
Released: 2026-07-31
Fixed β
- Boot-seeder no longer crashes when a storefront page was trashed. The default-content seeder now matches on the full unique key (slug + type + language) and ignores global scopes, so a soft-deleted Shop/Cart/Checkout/Account/Blog page is found (and restored) instead of re-inserted. Previously a trashed shop page made the seeder hit a duplicate-slug constraint on boot β on containerised installs this could crash-loop the app container (502 Bad Gateway). Each create is now wrapped so the seed can never fail the boot.
v2.2.3 β
Released: 2026-07-31
Added β
- All Google Fonts everywhere. Typography pickers now list the full Google Fonts catalogue (~1,900 families, grouped by category) instead of a short hand-picked set β in the Customizer and in every Falcon Builder element. Each font shows its own real weights, and fonts load on demand.
- Searchable font picker in the Builder. The element font-family control is now a searchable dropdown (like the Customizer), so you can type to find any font.
- One shared font source. A single
falcon_google_fonts()catalog feeds every typography UI β add a font once and it appears everywhere, no per-place lists to sync. - Title element supports inline HTML. Markup typed into a Title (e.g.
<b>,<span style>,<br>) now renders on the canvas and the front-end instead of showing as text.
Changed β
- Customizer URL simplified β
/admin/appearance/customizeris now/admin/customizer.
Fixed β
- E-commerce is part of the free core (carried from v2.2) β no Pro licence required.
v2.2.2 β
Released: 2026-07-31
Fixed β
- Update no longer reports "completed with errors" when the shop pages already exist.
falcon:update's e-commerce page creation now matches on the full unique key (slug + type + language) and ignores language scopes, so existing Shop/Cart/Checkout/ Account pages are found instead of re-inserted (which hit a duplicate-slug constraint).
v2.2.1 β
Released: 2026-07-31
Added β
- In-dashboard Pro updates. Dashboard β Updates now shows a FalconCMS Pro card alongside the core one: it detects a newer Pro release (via a public version manifest, since Pro is a private package), flags it with a NEW badge in the sidebar, and offers a one-click Update Pro Now button. The update is licence-gated β a valid, in-date subscription is required; an expired licence is prompted to renew instead of updating. On success, Pro's boot-time sync delivers any newly-bundled code and plugins (e.g. Falcon Slider) automatically.
v2.2 β
Released: 2026-07-30
Changed β
- E-commerce is now part of the free core. The complete shop system β products, variants, cart, checkout, orders, coupons, reviews and wishlist β no longer requires a Pro license. It works on every FalconCMS site, free forever. (Multi-language, analytics, the advanced builder, custom fields and Falcon Slider remain Pro.)
Added β
Falcon Slider β a new Pro plugin: a layer-based, Slider-Revolution-class slider builder. Design slides on a full-screen visual canvas with:
- Layers β text (with SEO
h1βh6tags), image, button, shape, icon, video (self-hosted / YouTube / Vimeo), audio, live countdown, and raw HTML/embed. - Per-layer timeline animation β 15 entrance/exit presets, text reveals (typewriter / split chars / split words), idle loops (float / bob / pulse / sway / spin), and per-layer delay Β· duration Β· easing.
- Backgrounds β colour, gradient, image, background video, colour & gradient overlays, Ken Burns and mouse parallax.
- Responsive β position, size, font-size and visibility per device (desktop / tablet / mobile), plus layer groups and global (every-slide) layers.
- Navigation β arrows, bullets, progress bar, thumbnails, autoplay, loop and pause-on-hover; auto / full-width / full-screen sizing.
- Productivity β pre-built template gallery, save-as-template, duplicate, import / export, version history (auto-snapshot on every save, 20 kept), full-screen live preview of unsaved changes, and whole-slide links.
- Performance β LCP background preload, layout-shift-free reservation, lazy media, and subset font/icon loading for Core Web Vitals.
- Embed with the
[falcon_slider id="β¦"]shortcode or the Falcon Slider Falcon Builder element. Governed by themanage_sliderspermission.
See the Falcon Slider documentation.
- Layers β text (with SEO
v2.0 β
Released: 2026-07-14 Β· current release v2.1.0
FalconCMS is now open-core. The core stays free and MIT-licensed; a new Pro edition unlocks the commercial features (e-commerce, multi-language, analytics, the advanced page builder, custom fields and advanced login). Existing sites keep working β nothing is taken away β and there is a launch grace window during which every Pro feature stays free. Features a site already used are grandfathered free on that site forever.
Added β
- Pro License page (Falcon Builder β License). Paste your license key to activate Pro, deactivate to release it, or hit Re-check now to re-validate on the spot. Each key is enforced per site (Pro = 1 site, Agency = unlimited).
- One-click Pro install. Paste the access token from your purchase and FalconCMS writes
auth.jsonand installs thefalconcms/propackage for you β no terminal needed. Manual Composer instructions remain as a fallback. - In-app updater (Dashboard β Updates). Check for and install the latest release from the browser, with a backup confirmation and a clear progress dialog.
- Freemium grace β a single fixed cutoff date (not a rolling per-site window), so the transition happens everywhere at once.
Changed β
- The "now freemium / upgrade to Pro" banners (admin and cart) disappear once a site holds a valid Pro license.
- Renamed the internal version constant to
FALCON_CMS_VERSION.
Fixed β
- Reliable updates & version reporting. The updater installs the exact latest release and reports the installed version correctly β no more "update available" immediately after updating.
- Shop product category now shows on the shop listing (some products previously read "Uncategorized"), with the category eager-loaded to avoid N+1 queries.
- Clear license messages β invalid key, activation-limit-reached and expired keys now say exactly what's wrong and how to fix it, instead of a generic notice.
- Updating core ahead of the Pro package no longer causes a fatal error.
Extensibility update. FalconCMS also gains a full plugin system β the functional counterpart to themes β plus a runtime API for adding admin menus, settings pages and settings fields without writing controllers, routes or views, and a security hardening pass on how settings are saved.
Added β Plugins & extensibility APIs β
Plugin system β see Plugins
- Drop-in plugins. A plugin is a folder in
plugins/with aplugin.jsonmanifest and an optionalplugin.phpbootstrap. Free and unrestricted β anyone can write, install and share them. - Plugins admin screen with two sub-pages: Installed Plugins (filter by All / Active / Inactive, search, and Activate / Deactivate / Update / Uninstall from row actions) and Add New (drag-and-drop
.zipupload, or install from a direct URL). - Convention-based loading.
src/is PSR-4 autoloaded,routes/web.phpis registered,resources/views/becomes aslug::namespace, anddatabase/migrations/runs on activation β no ServiceProvider needed (though one can be declared). - Lifecycle hooks β optional
activate(),deactivate(),uninstall()andupgrade($previousVersion)on a class named in the manifest. - Dependencies β declared plugins must be active first, are loaded in dependency order, and can't be deactivated or uninstalled while depended upon.
- Update detection β a newer version on disk than the one activated shows Update available; applying it runs new migrations and records the version.
- Requirement checks on activation for
requires_phpandrequires_cms. - Fatal-safe loading β a plugin that throws while loading is automatically deactivated and logged instead of taking the site down. A plugin that fails to load is never marked active.
- CLI:
plugin:list,plugin:activate,plugin:deactivate, andmake:plugin "Name"to scaffold one. manage_pluginspermission, assignable to any role.
Admin Menu API β see Admin Menu API
falcon_add_menu_page()/falcon_add_submenu_page()register sidebar items at runtime, merged into the DB-driven sidebar so they survivefalcon:update.falcon_add_options_page()renders a complete settings page β fields, saving and all β from an array. Supports a tabbed layout with deep-linkable?tab=.- New
falcon_admin_menuaction for deferred registration.
Settings Fields API β see Settings Fields API
falcon_add_settings_field()injects fields into the existing settings screens β General, SEO, REST API, Integrations and Shop β rendered as native rows and saved by that screen's own Save button.falcon_add_settings_tab()adds a new top-level tab to the Settings nav, with its own page at/admin/settings/{id}.- 18 field types: text, number, email, password, url, textarea, checkbox, select, radio, color, date, range, multiselect (searchable, chip-based), tags, image, file, wysiwyg and repeater.
- Shop fields can target a specific Shop settings tab.
- New
falcon_register_settingsaction, plus form hooks for the REST API, Integrations and Shop screens.
Changed β Plugins & extensibility β
- Plugin routes are registered before the frontend catch-all, so plugin URLs resolve instead of falling through to a 404.
- Themes and plugins now load at the same point in the boot cycle, giving plugins access to every hook a theme has β including register-time filters.
- The dashboard's built-in documentation viewer was removed; the documentation site is the single source of truth.
Security β
- Protected options. Internal keys β
falcon_license_*andfalcon_grandfathered_featuresβ can no longer be written through settings saves, injected fields or options pages. Previously a crafted settings request could overwrite the cached license state and unlock Pro features. - URL scheme validation on
imageandfilefields: onlyhttp,httpsand relative paths are rendered, blocking storedjavascript:payloads. - Identifier sanitisation β field and tab ids are restricted to
AβZ aβz 0β9 _ -before reaching markup or inline scripts.
Fixed β Plugins & extensibility β
- Shop settings nav highlighted two tabs at once (a static class fought the reactive one).
- The Installed Plugins sidebar item no longer stays highlighted while on Add New.
v1.8.3 β
Released: 2026-07-04
A Layout Builder fix: every layout's every section now toggles fully independently.
Fixed β
- Layout sections are now independent per layout. Enabling a section (notably Content) in one layout no longer makes it appear active in the Global Layout too. The Layout Builder was falling back to "the first published section" for any slot the Global Layout hadn't explicitly assigned, which made a section enabled elsewhere show up as active on Global. Each slot of each layout now reflects only its own assignment and on/off state β matching what the frontend renders.
v1.8.2 β
Released: 2026-07-04
A Layout resolution refinement: header, title bar and footer now cascade cleanly from the custom layout down to your defaults, so content is never left without chrome.
Changed β
- Layout slots now cascade: custom layout β Global Layout β theme default. For content matched by a custom layout, if its Header/Title Bar/Footer is toggled off or left unassigned, the slot now inherits the Global Layout's header/footer for that content. If the Global Layout has nothing selected either, the theme's built-in default renders β everywhere (frontend and the builder canvas preview). This supersedes v1.8.1's "disabled slots render nothing": a slot with no active assignment always falls through to the next level rather than showing blank space.
v1.8.1 β
Released: 2026-07-04
A builder-experience & polish release: the page/post builder canvas now previews the real header, page title bar and footer around your content, plus fixes for headings in the classic editor and the admin Customizer menu placement.
Added β
- Live header / title bar / footer preview in the builder β when you design a page, post, CPT or product (not a Layout template), the canvas now shows the actual Header, Page Title Bar and Footer that the applicable Layout assigns to it, rendered through the real theme so it looks like the live page. They're read-only here β hover shows an Edit β¦ Layout Section button that opens that section in the Layout Builder. A slot is previewed only when it's enabled in the layout.
Changed β
- Rich Editor headings β the Paragraph / Heading 1β6 dropdown is back in the classic editor (it was using a removed TinyMCE 5 control name).
- Customizer now lives under Falcon Builder on existing sites too β a migration moves the Customizer menu item out of Appearance and under Falcon Builder (fresh installs already got this); a legacy "Lazy Builder" menu is renamed to Falcon Builder.
- Disabled Layout slots render nothing β when the Layout Builder is in use, a header/title-bar/footer that is toggled off or unassigned no longer falls back to the theme's built-in chrome (on the frontend and in the builder preview).
Fixed β
- Classic-editor headings now use your Customizer heading sizes instead of shrinking to paragraph size (Tailwind's preflight was overriding bare
h1βh6; the page builder was already unaffected). - Hairline gap between the page content and a full-width footer (a 1px sub-pixel seam showing the body background) is gone.
- Fixed an infinite recursion that could return a 500 when a page is rendered as its own content (e.g. the Home page inside its assigned footer).
v1.8.0 β
Released: 2026-07-03
A major builder release: a dedicated Layout Builder for site-wide templates, a new Bread Crumb element, dynamic image backgrounds for containers and columns, and a far more consistent Site Width / Full Width system.
Added β
- Layout Builder β design site-wide Header, Footer, Page Title Bar and Content templates in the Falcon Builder and assign them globally or by condition. Includes an in-card layout picker, a conditions modal (target a custom layout to specific pages, post types or archives), a per-layout enable/disable toggle (AJAX), and Export / Import of layouts.
- Custom 404 page β build your own "Not Found" page in the Layout Builder; the theme renders it automatically.
- Bread Crumb element β a new builder element that outputs the current page's breadcrumb trail (Home β post type / category β current page), with full typography, colour, separator and alignment controls, plus Schema.org
BreadcrumbListstructured data for SEO. - Dynamic image backgrounds β containers, columns and nested columns can now use a dynamic source (Feature Image, Author Avatar or Site Logo) as their Background Image, resolved per-post on the frontend. It layers correctly beneath a Background Gradient, and the builder canvas previews it too.
Changed β
- Consistent Site Width / Full Width β a container set to Site Width now always constrains to your Customizer Site Width (centered), independent of the Customizer's Boxed/Wide layout, and matches the builder canvas exactly. Full Width containers always span edge-to-edge.
- Customizer moved under Falcon Builder β Appearance β Customize now lives in the Falcon Builder menu; the sidebar's "Lazy Builder" was renamed to Falcon Builder with corrected submenu links, and the standalone Header/Footer builder entries were removed (they live in the Layout Builder now).
- Product sorting on the shop and product archives only appears when products actually exist.
- Hardened ACPT import/export β re-imports are idempotent, taxonomy terms keep their
cpt_slug, and post export is more complete.
Fixed β
- The Post Content element set to Full content no longer breaks plain/classic content out to the viewport edge β it now respects its parent container's width (it still full-bleeds when the content is itself a builder layout with self-boxing sections).
- Dynamic backgrounds render inline (no lazy-load dependency) so they paint reliably; the builder canvas shows a neutral "Feature Image" placeholder when editing a template that has no specific post, instead of an unrelated image.
v1.7.4 β
Released: 2026-06-30
A portability & accounts release: import/export for forms and builder-library items, an email-verification toggle, and a much smarter media backup/restore. Now officially runs on Laravel 13 as well.
Added β
- Form import/export β every form can be exported to a portable
.jsonfile (structure + settings) and imported on any FalconCMS site as a new form, straight from the Forms list - Post Card & Mega Menu import/export β builder-library items export to
.jsonand import back as new items (with fresh IDs), so designs move easily between sites - "Require email verification" toggle β Settings β Membership now lets the site owner choose whether new users must verify their email before signing in, or are logged in immediately after registering
Changed β
- Smarter media backup & restore β a media-only backup now bundles the Media Library records too, so restoring brings the library entries back (not just the files); restore also auto-detects and strips a wrapper folder (e.g. when a downloaded backup was unzipped and re-zipped), and preserves the full
Year/Monthfolder structure - Deleting a media item now removes its generated size variants too (e.g.
image-300x200.jpg), matching WordPress β files that are tracked as their own media item are left alone - Honest registration feedback β if the verification email can't be sent, registration now says so plainly instead of falsely claiming a link was sent
- Laravel 13 support β added to the documented requirements (Laravel 10, 11, 12, or 13)
Fixed β
- Media-only restore now places files at their correct paths (including the
media/sub-folder) instead of flattening them
v1.7.3 β
Released: 2026-06-30
A tooling & migration release: a new Export/Import pair, one-click Clone for every content type, a smarter Backup tool, plus several builder, security and migration fixes.
Added β
- Tools β Export β a feature-driven export screen: it lists every registered post type, taxonomy and the media library automatically (so future exportable features appear on their own) and downloads a WordPress-compatible
.xml(WXR) file. Pick All content or a single source - Tools β Import β the counterpart to Export: upload an export
.xmland it restores posts, pages, custom post types and taxonomy terms (also accepts standard WordPress WXR files) - Clone for posts, pages, products & CPTs β every list row now has a Clone action (next to View) that duplicates the item β and its taxonomies, custom fields and (for products) shop data, variations & downloads β into a fresh draft
- Duplicate menu β the menu editor gains a Duplicate Menu action that copies a navigation menu with its full item hierarchy (the copy is never auto-assigned as header/footer)
Changed β
- Backup tool reworked β one Create Backup button with three choices: Only Database, Only Media, or Database + Media (a single archive carrying both). Restore is now content-aware β it detects from the file itself whether to restore the database, the media, or both, so a whole site can be moved to another install with one file. Uploaded backups are detected the same way
- Live gallery hover effect on the canvas β the Gallery element's Zoom hover now previews in the builder, matching the front end
- Column / nested-column hover effects now work on the front end β Zoom / Lift / Glow / Fade hover types rendered only in the builder before; they now render on the published page too
- Buttons without a link render cleanly β a Button with an empty Link URL no longer outputs an empty
<a>tag or a pointer cursor; any value (including#) makes it a real link again - Clearer import results β re-importing items that already exist now reports them as skipped (including taxonomy terms) with an explanatory note, instead of showing all zeros
Fixed β
- Stored-XSS hardening β classic (non-builder) post/page content is now sanitised on output (scripts,
on*handlers andjavascript:URLs are stripped), closing a gap that affected imported HTML content - Menu save error β saving a menu no longer fails with Unknown column
mega_menu_id; the relevant migration now runs, and several migrations were made idempotent (guarded withhasTable/hasColumn) sophp artisan migrateruns cleanly on fresh, partially-migrated or already-migrated installs β without any data loss - Menu selector β choosing a menu from the dropdown no longer auto-opens it; the Select button is the trigger
- Nested-row layout consistency on the builder canvas
v1.7.2 β
Released: 2026-06-27
A builder polish & tooling release: every Font Awesome free icon in the icon pickers, a media-files backup option, plus several nested-layout and colour-picker fixes that make the builder canvas match the front end.
Added β
- Media files backup β Tools β Backup now has a Backup Media Files button that zips everything under
storage/app/public(uploads, generated images, etc.) into a downloadable archive, and restores media archives back into place. Database snapshots are unchanged - Every Font Awesome free icon in the builder β the icon pickers (Icon Box, Button icon, Icon List and custom icon fields) now list the full Font Awesome 6 free set β 2,060 icons across Solid, Regular and Brands (up from a few hundred). A search box reaches any icon, with the grid capped for snappy scrolling
Changed β
- Icon Box font size accepts any CSS unit β the Title and Description Font Size fields lost their
px/remdropdown and now take a free-form value (px,rem,em,%,vw,vh,calc()), matching the Title element - Nested-column Border & Box-Shadow colour pickers unified β they now use the same round-swatch + editable hex design as every other picker, show the opacity-aware
#RRGGBBAAcode, and the colour renders with its opacity on canvas and front end (responsive per-device)
Fixed β
- Nested rows match the front end on the canvas β a nested row no longer shows a permanent whitish box; it renders transparent (like a normal element) and reveals its outline + ROW badge only on hover, with no extra padding gap between the row and its parent
- No more phantom vertical gap inside nested columns β columns with default alignment no longer stretch their inner content to a taller sibling's height in the builder, so spacing inside nested columns now looks exactly like the published page
v1.7.1 β
Released: 2026-06-26
Changed β
- Analytics "Page" column shows the site domain for homepage visits β homepage hits (including bots that reach the site by raw IP) now display the configured site domain (e.g.
demo.example.com) instead of a bare/. Other pages still show their request path
v1.7.0 β
Released: 2026-06-26
A builder & design-tooling release: one unified colour picker everywhere, responsive background hover colours, full CSS-unit support for font sizes, plus several builder and analytics fixes.
Added β
- Background Hover Color for Containers, Columns & Nested Columns β a new responsive hover colour (separate desktop / tablet / mobile values). It previews live on hover in the builder canvas and renders as a real
:hoverrule (with media queries) on the front end - Custom Text Color for Buttons β when Button Style β Custom is selected, a dedicated text-colour picker sits with the gradient colours; the default style keeps its own text colour
Changed β
- One unified colour picker across the whole CMS β the main builder, the mega-menu & post-card builders, the Theme Customizer and the Form builder now share a single clean picker: a round swatch, an editable hex field, and a compact popup (saturation square + hue + alpha sliders) with the alpha bar tinted to the current colour. The Form-builder picker also gained an opacity slider
- Opacity-aware colour fields β fields that store opacity separately now show the full 8-digit
#RRGGBBAAcode, and the alpha slider opens at the correct position - CSS units for every font size β all typography / font-size inputs across builder elements (and inside header / footer / nested layouts) now accept
px,rem,em,%,vw,vhandcalc(). Values apply on both the canvas and the front end and survive the shortcode round-trip - Title element typography now mirrors the Text Block (font family, weight, size, line-height, letter-spacing, transform) for a consistent editing experience
Fixed β
- Column / nested-column background colour ignored responsive values β tablet/mobile background colours were rendered with the desktop value on both the canvas and the front end; per-device colours are now honoured
- A per-device colour was discarded when switching device β picking a tablet/mobile colour and then toggling the device preview reverted it; the colour is now committed instead of reverted
- Analytics "Page" column showed the raw server IP β visitors who reached the site directly by IP (bots/scanners) appeared as
https://<ip>; the column now shows a clean request path - Documentation clarifies that MySQL / MariaDB are the only fully supported databases (SQLite is partial and not recommended; PostgreSQL / SQL Server are unsupported)
v1.6.3 β
Released: 2026-06-25
Fixed β
- Reinstalling over an existing database failed with "table already exists" β Running
falcon:install(orfalcon:update) on top of a database that still had some tables β afterfalcon:uninstall-db, or when installing onto an existing Laravel app whoseusers/cache/jobstables remained β mademigratetry to recreate them and abort. The commands now reconcile first: any migration whose created tables already exist is recorded as run, somigrateskips it and only creates what is genuinely missing. This works for both the app's own and the package's migrations, without editing any migration file
v1.6.2 β
Released: 2026-06-24
Fixed β
- Uninstall could leave a broken
Usermodel βfalcon:uninstallremoved theHasCmsPermissionsimport but only stripped a standaloneuse HasCmsPermissions;line. When the trait was declared in a combined list (e.g.use HasFactory, Notifiable, HasCmsPermissions;), the reference was left without its import, crashing the app β and any later reinstall's migrations β with "Trait App\Models\HasCmsPermissions not found". The revert now also removes the trait from a combineduselist (verified valid for leading/middle/trailing positions)
v1.6.1 β
Released: 2026-06-24
Fixed β
- Dashboard showed a stale "Installed Version" β After updating, the dashboard kept showing an old installed version (e.g. v1.4.2) even though the new code was in place. The version check preferred Composer's reported version, which can be a pinned alias (notably on path-repository installs) and lags behind. It now reads the version from the package's
version.jsonfirst (bumped on every release), so the dashboard reflects the version actually installed
v1.6.0 β
Released: 2026-06-24
A consolidation milestone that brings together everything shipped across the 1.5.x line.
Highlights β
- Dashboard β Redesigned e-commerce KPI cards with month-over-month trend deltas; Top Selling Products, Low Stock and Recent Orders widgets; and an interactive Orders by Country world map (zoom, pan and per-country hover). The whole e-commerce section is now gated behind the
access_shoppermission - Analytics β A Visitors by Country world map, a named Traffic Sources breakdown (Google, Facebook, Instagram, YouTube, β¦ Direct, and other sites), and hover tooltips on the real-time active-users sparkline
- Shop β The Conversion Funnel (visitors β product β cart β checkout β orders) now lives on the Shop Overview
- Security & reliability β Internal AJAX fragment endpoints redirect on direct visits instead of leaking raw JSON; reliable geolocation via the shared
falcon_geoip()helper; a richer IP blacklist (location, ISP, first/last seen) - Lifecycle β New
falcon:uninstall(full, leaves the app booting cleanly) andfalcon:uninstall-db(database-only) commands, plus idempotent core migrations so a reinstall always succeeds
For the granular history of these changes, see the 1.5.x entries below.
v1.5.10 β
Released: 2026-06-24
Fixed β
- App crashed after a database reset β The redirect middleware queried
cms_redirectson every request and returned a 500 ("Base table or view not found") once the tables were dropped (e.g. afterfalcon:uninstall-db). It now checks the table exists first and degrades gracefully when it doesn't - Reinstall failed with "table already exists" β Uninstall keeps the shared Laravel tables (
users,sessions,cache,jobs) but clears the migration records, so re-runningfalcon:install/migratetried to recreate them and failed with "Table 'users' already exists". The bundledusers/cache/jobsmigrations are now idempotent (Schema::hasTableguards), so a reinstall succeeds no matter which tables remain
v1.5.9 β
Released: 2026-06-24
Fixed β
- Uninstall left a stale provider cache β
falcon:uninstallremoves the package withcomposer remove --no-scripts, which doesn't regenerate Laravel's package-discovery cache.bootstrap/cache/packages.php/services.phptherefore still referencedFalconCmsServiceProvider, so the app booted with "Class FalconCms\Core\FalconCmsServiceProvider not found". The command now clears those bootstrap caches as its final step. (If you hit this after a manualcomposer remove, deletebootstrap/cache/packages.phpandbootstrap/cache/services.php, then runcomposer dump-autoload.)
v1.5.8 β
Released: 2026-06-24
Fixed β
- Uninstall left a broken
Usermodel β The earlier uninstall dropped tables and files but did not remove theHasCmsPermissionstrait the installer added toApp\Models\User, so aftercomposer removethe app crashed with "Trait FalconCms\Core\Traits\HasCmsPermissions not found". The full uninstall now reverts that automatically
Added β
falcon:uninstallβ full removal (no leftovers) β Reverts the trait/import added toApp\Models\User, drops tables + migration records, removes published files, and runscomposer remove falconcms/falconcmsβ leaving the app booting cleanly. Options:--all(also drop shared Laravel tables),--force,--keep-files,--no-composerfalcon:uninstall-dbβ database-only removal β Drops just the FalconCMS tables (and migration records); the package code, files and User model trait stay in place (e.g. to wipe data and re-migrate). Options:--all,--force
v1.5.7 β
Released: 2026-06-24
Added β
falcon:uninstallcommand β Cleanly removes FalconCMS: drops its database tables, deletes its rows from themigrationstable (so a later reinstall re-runs cleanly), and removes published views, themes and assets. Shared Laravel tables (users,sessions,cache,jobs, β¦) are kept by default to avoid breaking the host app;--alldrops them too for a full wipe. Options:--force(skip the confirmation),--all,--keep-files. Finish withcomposer remove falconcms/falconcms
v1.5.6 β
Released: 2026-06-24
Fixed β
- IP Blacklist β country always "Unknown" β Blocked IPs were geo-resolved with
file_get_contents, which is disabled or blocked on many production hosts, so the country never resolved. A new sharedfalcon_geoip()helper now uses the Laravel HTTP client (with a timeout, cached 30 days); existing "Unknown" rows are backfilled when the blacklist page is viewed
Added β
- IP Blacklist β richer detail β The blacklist table now shows Location (country + city/region), ISP / network, and both First Blocked and Last Attempt times, with an attempts badge. New blocks capture city, region and ISP
Changed β
- Geo lookups unified β Visit tracking and the IP blacklist now share the same cached
falcon_geoip()helper instead of separate, less reliable lookups
v1.5.5 β
Released: 2026-06-24
Security β
- AJAX fragment endpoints no longer expose raw output on direct visit β
GET /cart/fragment(mini-cart) andGET /search/liveare internal AJAX-only endpoints; opening them directly in a browser previously returned their raw JSON. Non-AJAX (direct navigation) requests are now redirected to the cart and search pages respectively, so the raw payloads are never shown. JS-driven calls (which sendX-Requested-With) are unaffected, and only ever returned the visitor's own session data anyway
v1.5.4 β
Released: 2026-06-24
Added β
- Dashboard β Orders by Country map β An interactive world map highlighting the countries orders came from (shaded by volume), with zoom buttons, mouse-wheel zoom, drag-to-pan and per-country hover (country name + order count), plus a top-countries list. Country values are normalized to ISO-2 from mixed order data
- Dashboard β Top Selling Products, Low Stock & Recent Orders β The redundant "Quick Stats" panel is replaced by a best-sellers list (units sold + revenue) and a low-stock alert list; a Recent Orders table now fills the space under the revenue chart
- Analytics β Visitors by Country map β The same interactive world map for geo-located visits
- Analytics β Traffic Sources β A named-source breakdown (Google, Bing, Facebook, Instagram, YouTube, X, LinkedIn, TikTok, β¦ Direct, and any other site by domain) with visit counts, percentages and favicons
- Analytics β Real-time sparkline tooltip β Hovering the real-time active-users bars now shows the visitor count for that minute
Changed β
- Dashboard β E-commerce KPI cards redesigned β Accent strip, soft-tint icon, month-over-month trend delta (β/β %) and a contextual subtext per card
- Dashboard β Shop section permission-gated β The whole e-commerce section (revenue, orders, customer names) now requires the
access_shoppermission (admins bypass), so it is no longer shown to every dashboard-accessing role - Shop β Overview β Conversion Funnel β The conversion funnel (visitors β product β cart β checkout β orders) and conversion rate now live on the Shop Overview, moved from Analytics to keep shop metrics together
v1.5.3 β
Released: 2026-06-23
Fixed β
- Registration β default role ignored β Self-registration now assigns the role configured in Settings β New User Default Role instead of always using subscriber. Selecting a different role (e.g. Editor, Author) now correctly applies it to newly registered users; if the configured role is missing it safely falls back to subscriber
v1.5.2 β
Released: 2026-06-23
Changed β
- Device limit β simpler on/off model β The multi-device setting is now a clear cap. Unchecked = unlimited devices; checked = limit concurrent logins to Max devices allowed. The
-1"unlimited" sentinel has been removed β the field is a plain positive number again (minimum 1), and the checkbox/help text now reflect the inverted meaning
v1.5.1 β
Released: 2026-06-23
Fixed β
- Multi-device login β unlimited (
-1) β Setting Max devices allowed to-1now correctly means unlimited concurrent sessions and never blocks sign-in. Previously the limit check (active sessions β₯ -1) was always true, so logging in from a second device failed with "Login denied: Only one active session is allowed per account." The-1sentinel now applies regardless of the multi-device toggle; normal numeric limits and the single-session default are unchanged
Changed β
- Settings β Max devices allowed β The field now accepts
-1(minimum lowered from1) with a helper note that-1means unlimited devices
v1.5.0 β
Released: 2026-06-22
Fixed β
- Registration β duplicate username β Usernames derived from the email local part are now sanitized and made unique (
john@a.comandjohn@b.comno longer collide βjohn,john1β¦), fixing the duplicate-username error on sign-up - Admin user create/edit β Validation errors are now displayed (a top summary plus per-field messages) instead of a database constraint crash; inputs repopulate on failure, and a success message is shown
- User update redirect β Saving a user now returns to the same edit page with the success notice, instead of jumping to the user list
Added β
- Password strength & match β The admin user create/edit password fields now show a live strength meter and a password-match indicator, matching the registration page
v1.4.9 β
Released: 2026-06-22
Added β
- Analytics β major overhaul β Bot/crawler filtering, geo location (country/city with flags), real-time active users with a 30-minute sparkline and live tables, sessions, bounce rate, new vs returning visitors, traffic channels, e-commerce conversion KPIs and a visitβcartβcheckoutβorder funnel, plus donut charts for channels, returning visitors and top countries
- Analytics β data retention β New
falcon:prune-analyticscommand with a daily schedule and a cron-independent fallback, with a configurable retention window
Fixed β
- Footer logo β The default footer logo now uses the white brand logo (the dark logo was invisible on the dark footer) at a larger size, automatically darkened on light footer backgrounds; a custom uploaded logo is always shown as-is
v1.4.8 β
Released: 2026-06-22
Added β
- Registration β email verification β New sign-ups are no longer logged in immediately; a time-limited (5-minute) signed verification link is emailed instead, and sign-in is blocked until the address is verified. Includes a notice page and a throttled resend flow. A migration marks all existing users as verified so no one is locked out
Fixed β
- Order status emails β Customers are now emailed on every order status change (pending, on-hold, processing, completed, delivered, cancelled, refunded, partially-refunded, failed), not just on delivery β for both single and bulk updates
Changed β
- Product Meta element β Now available only in post-card mode, like Post Meta and Content
v1.4.7 β
Released: 2026-06-21
Added β
- Builder β Product Meta element β A new element that displays a product's price (with sale), SKU, availability, stock quantity and type; each field toggleable, with stacked/inline layout, alignment, labels and full design controls
- Builder β Ticker β Configurable item spacing, a duplicate-item button, and live scrolling in the builder canvas
- Dynamic sources β Product group β Bind any text field to live product data (price, regular/sale price, SKU, stock status, stock quantity); dynamic fields now show a live preview right in the builder using the real value of the post being edited
v1.4.6 β
Released: 2026-06-21
Fixed β
falcon:updateβ stale published view overrides β Update now removes the entire publishedresources/views/vendor/falcon-cmsdirectory, not just theadminsubfolder. A leftover published copy of a namespaced package view (e.g.frontend/builder/column.blade.php) silently shadows the real vendor view, so layout fixes never appear on the site no matter how many caches are cleared. Clearing the whole override namespace guarantees the package's own views are always used
v1.4.5 β
Released: 2026-06-21
Fixed β
- Dashboard Update β stale frontend after update β The dashboard "Update" now resets the php-fpm OPcache from the web request itself. Previously the
falcon:updatesubprocess ran under CLI php, whoseopcache_reset()only clears the CLI OPcache β the php-fpm workers that serve frontend pages kept executing the old compiled Blade views, so builder/layout fixes did not appear on the live site until a manual container restart - Dashboard footer β Default admin footer credit changed to "Theme developed by Falcon CMS"
Changed β
- Taxonomy screens β Removed the non-functional "Screen Options" and "Help" buttons from the top-right of all taxonomy list pages (Categories, Tags, Product Categories, Product Tags, and custom ACPT taxonomy terms)
v1.4.4 β
Released: 2026-06-21
Fixed β
- Dashboard Update β php-fpm binary β The dashboard "Update" button ran
falcon:updatewithPHP_BINARY, which in a web (php-fpm) request points at the php-fpm executable and cannot runartisan(it printed FastCGI usage and aborted, so migrations/cache-clear/OPcache reset never ran). The updater now locates a real CLI php binary, checking absolute paths first since the php-fpm worker often runs with a strippedPATH
v1.4.3 β
Released: 2026-06-21
Fixed β
- Page Builder β Preview mode blank canvas β Toggling the builder's eye-icon Preview no longer blanks the whole canvas. In preview the canvas kept
grid-area: auto, which auto-placed it into the now-hidden sidebar's 0-width grid column; it is now pinned to its namedcanvasarea so the design stays visible
v1.4.2 β
Released: 2026-06-21
Fixed β
- Page Builder β Row content layout β Elements inside a column with Content Layout set to "Row" now stay side-by-side and never wrap to the next line (
flex-wrap: nowrap); previouslyflex-wrap: wrapcaused elements to stack when they did not fit falcon:updateβ OPcache β OPcache is now reset after cache clearing so freshly compiled Blade views are served immediately without requiring a server restart
v1.4.1 β
Released: 2026-06-21
Fixed β
- Multi-device login β
-1value for Max Devices now correctly means unlimited; previouslycount() >= -1was always true, blocking all logins even when unlimited was intended - Page Builder β Nested Column row layout β Elements inside a column with Content Layout set to "Row" now render side-by-side on the frontend; previously
width: 100%on element wrappers caused items to stack vertically despiteflex-direction: row
v1.4.0 β
Released: 2026-06-20
Added β
- Demo mode β Login page β Demo credentials box displayed above login form when
APP_DEMO=true - Demo mode β User management β All fields on user create and user edit pages disabled with warning banner when
APP_DEMO=true - Demo mode β Settings β
register_urlandlogin_urlinputs disabled with warning banner whenAPP_DEMO=true - Docs β Demo page β Live demo request page with lead capture form; credentials sent to visitor's email via EmailJS after form submission
Fixed β
- Footer logo β Default FalconCMS logo always shown in footer column 1; embedded as base64 to remove file dependency;
theme_footer_logo/theme_site_logocleared from DB onfalcon:updateso stale overrides are never applied falcon:updateβ Published admin views deleted on update so vendor views are always served fresh (no stale published copies)
v1.3.18 β
Released: 2026-06-20
Added β
- Customizer β Performance β "Clear All Cache" button for one-click cache clearing from the admin
Fixed β
- Product editor β Added
x-cloakto product data metabox to prevent Alpine.js FOUC on page load falcon:updateβ Admin views automatically re-published during update to keep published copies in sync- Sale end date β
sale_ends_atdatetime input minimum set using client-side local time instead of server UTC - Product archive β
productCategoriesrelation used inarchive-product.blade.php; eager loaded on CPT archive queries to prevent N+1 - Sale end date validation β Removed
after:nowrule causing false rejections in some timezones - PHP_BINARY β Correctly resolved to CLI
phpin web (php-fpm) context - Product categories β Category label display corrected on product cards and single product pages
- Shop β Tab active-state bug fixed;
hold_stockorder cancellation implemented - Page Builder β Fixed offset constants in
parseColumnsFromContent() - Hooks & helpers β Remaining
lazy_class and helper references renamed tofalcon_
v1.0.0 β
Released: 2026-06-15
Initial public release of FalconCMS β a powerful Laravel CMS package with page builder, e-commerce, and a WordPress-like admin dashboard.
Core β
- WordPress-like Admin Dashboard β Sidebar navigation, top bar, role-based permissions, activity logs
- Page Builder (Falcon Builder) β Drag-and-drop visual editor with rows, columns, and element blocks
- Post & Page Management β Custom post types, categories, tags, featured images, SEO fields
- Media Library β Upload, manage, and select images/files across the admin
- User & Role Management β Granular permission system with custom roles
- Multi-language Support β Built-in language management
- Theme System β Installable themes with Customizer support (header, footer, colors, typography)
- Hook Architecture β WordPress-style
add_lazy_action/add_lazy_filterfor extensibility - Custom Options Pages β Register custom settings pages via config
E-Commerce (Shop) β
- Product Management β Simple and variable products, SKU, stock, sale price with scheduled expiry (
sale_ends_at) - Digital / Downloadable Products β Attach files from the media library; secure token-based download links with expiry and download count limits
- Orders β Full order lifecycle (pending β processing β shipped β completed), order notes, status history
- Cart & Checkout β AJAX cart, coupon codes, shipping zones, tax rules
- Payments β Cash on Delivery, Stripe, SSLCommerz integrations
- Customer Account β Order history, downloads tab, address management
- Sales Reports β Revenue by period (daily/weekly/monthly), top products, customer LTV, CSV export
- Shop Settings β Currency, inventory, email notifications, shipping, tax, coupon management
Admin UI β
- URL-aware Settings Tabs β Tab switches update the browser URL via
history.replaceState - Sidebar Collapse β "Collapse Menu" button; icon-only mode persisted in
localStoragewith no flash on navigation - FalconCMS Branding β FCM logo in admin top bar
Security β
- HTTP Security Headers β
X-Content-Type-Options,X-Frame-Options,Referrer-Policy,Permissions-Policy, CSP, HSTS - Rate Limiting β Login, forgot-password, comments, cart operations, file downloads
- CSRF Protection β All state-changing routes protected
- Input Validation β Cart quantities, file uploads, comment length, user enumeration prevention
- Secure Downloads β Token-based file delivery; tokens expire and have per-user download limits
Developer Tools β
- Artisan Commands β
lazy:expire-sales(scheduled sale price cleanup) - REST API β Configurable API key authentication
- Backup & Snapshots β Database and file backup tools
- WordPress Import β Import posts from a WordPress XML export
- Analytics Dashboard β Basic traffic and content stats
- Maintenance Mode β Toggle from Customizer with custom message and countdown timer
