Yuvomi
Self-hosted family planner for tasks, calendar, shopping, meals, and budget
Alternative to: cozi, familywall, skylight

v2.38.0
2026-08-24Added
-
The shared empty-state renderer covers all four shapes.
public/utils/empty-state.jsis a public browser library (see MODULES.md), and it previously offered only what the four kitchen tabs needed: one element, one call to action, a mandatory title. New:emptyStateHTML()andemptyHintHTML()for callers that build template strings, acompactvariant, an optional title,actions(plural) for the rarer state with two ways out,detailsfor a collapsible technical block, andclassNameon both the container and the button.The string form is deliberately
emptyStateEl(...).outerHTMLrather than a second composition - a parallel string version is exactly the mechanism that let these states drift apart in the first place. AnonClickdoes not survive serialisation and is therefore a hard caller error instead of a silently dead button.Two markup details changed for anyone selecting into it: the description is now a
<p>instead of a<div>(it is a sentence of prose, and the hint below it always was one), and a missing title no longer renders an empty<h2>- the element is omitted. A heading without text is worse for a screen reader than no heading.
Changed
-
Every empty state in the app now speaks the same grammar (#496). The shared renderer had been rolled out to the four kitchen tabs in July and stopped there; the remaining 15 pages kept assembling the markup by hand. What that left behind, measured across those pages: 52 hand-rolled empty states, not one of them carrying an ARIA role, 48 using a
<div>where the title should be a heading, and four load errors with no way out at all. So no “nothing found” was ever announced, no error was recognisable as one, and on an otherwise blank page the first screen of a module had no heading at all.The global error screen behind a failed route now uses the same grammar. It already had its role and its way out right, but its title was a
<div>too. -
Updated the dependencies:
googleapisto 176 and the development-onlypuppeteerto 25.8, plusopenid-clientto 6.8.7, and realigned theallowScriptsbuild-script pins to match. The twogoogleapismajors breakmerchantapi,discoveryengine,securityposture,computeandassuredworkloads- none of which Yuvomi uses; of that bundle it touches only Calendar v3 and Drive v3.
Fixed
-
A server error no longer claims there is nothing there. Tasks, Budget and Calendar reported a failed load through a toast alone, emptied their collection on the way, and left the empty state standing underneath. Of the two statements the wrong one survived: the toast faded after seconds, the claim stayed. On an HTTP 500 the tasks page said “No tasks - all done?” with “Create task” as the only offer, Budget said “No entries this month”, and the calendar showed an empty month grid (its agenda view, “No appointments”). All three offered a writing action as the only way forward, on a screen whose data was in fact still there. Each now keeps the error object, checks it before the empty branch, and shows the status code with a retry.
-
Four error states were dead ends with no action at all: Subscriptions, Housekeeping, Rewards and the shared expenses inside Budget. Housekeeping also printed the raw
err.messageas its explanation, which on every route is the untranslated English “Internal server error.” sitting in an otherwise translated interface; Budget’s shared expenses used the module name as the error title and so read like an empty page. -
A search term containing
&,<or>displayed as&in the “no results” line on the tasks page. The term was escaped once before being handed to the translation function and once more on the way into the markup.