Skip to content
View in the app

A better way to browse. Learn more.

ernestdefoe.online

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
ernestdefoe.online

Extensions, themes & support for Flarum and Invision Community

Vibe coding for the community web. Report a bug, request a feature, or dig into the source — this is where the tools you use get built, in the open.

We do custom Bespoke Invision Community apps. If you have an idea for something you want then use the contact form to get in touch with us.
Knowledge base

Things that cost me a day, so they cost you none

Working notes from building Invision Community and Flarum applications. Mostly the failures that give no error at all — the ones where everything installs cleanly and quietly does the wrong thing.

92 articles

Invision Community 5

86 articles

Extensions and contracts

39

What each extension point is for, what it must declare, and what happens when it is wrong — which is usually nothing visible.

Languages and text

5

The string table, translation, and the places where text does not appear where you expected it to.

Theming, templates and forms

9

Theme hooks, CSS that survives both colour schemes, and building forms that do not throw on render.

Background work and scheduled tasks

5

The queue system, work that has to happen after the response, and jobs that finish without doing anything.

Data, settings and storage

11

The database layer, settings, tags, file storage, and backing up a live site.

AI features and expectations

5

What these features do, what they cost, and what buyers reasonably but wrongly assume they do.

Application structure and releases

11

The JSON files an application is made of, versioning and upgrade steps, and testing from the command line.

Realtime, chat and calls

1

WebSocket gateways, relays and the server-side pieces live features depend on — where "it works when I test it" and "it works for your members" are different claims.

Nothing matches that.

Application structure and releases

The JSON files an application is made of, versioning and upgrade steps, and testing from the command line.

11 Articles in this category

  1. Ernest Defoe ·
    If you are building anything that needs a third party to act on a member's behalf — an AI connector, a mobile app, a desktop client, an integration a customer authorises — the instinct is to invent a token scheme. A long secret in a URL, an API key in a settings field, a bearer token you mint yourself. Do not. Invision Community 5 ships a complete OAuth 2.1 authorization server, and almost nobody building on the platform seems to know it is there. It is not a stub. It supports PKCE, refresh tok
    • 0 comments
    • 2 views
  2. Ernest Defoe ·
    These six were all found in a single application, over a single week, and they have one thing in common: none of them produces an error that points at the mistake. Four produce no error at all. One produces a blank 500 whose stack trace blames the wrong line. One leaves a page that still looks styled while a rule you wrote is quietly missing. They are ordered by how hard they are to notice, hardest first. If you are auditing an existing application rather than reading straight through, the las
    • 0 comments
    • 4 views
  3. Ernest Defoe ·
    Your application offers members a set of images to use as their profile photo — avatars you supply, badges, team crests, anything shared. It works. Then one member picks a different one, and the image disappears for everyone else who chose it. No error, no log entry; just a broken avatar on other people's posts, discovered days later. This is not a bug in your code so much as a consequence of how Invision Community stores profile photos, and it is easy to walk into because the obvious implemen
    • 0 comments
    • 8 views
  4. Ernest Defoe ·
    Invision Community 5's rich-text editor is TipTap, shipped as a compiled bundle. There is no source and no npm package, but there is a real third-party plugin API — and almost every way of getting it wrong fails silently. The editor loads perfectly, your button is simply absent, and there is nothing in any log to tell you why. How an application ships editor JavaScript Put plain .js files in applications/<app>/dev/editor/. Building the application writes them into data/editor.xml, and a
    • 0 comments
    • 16 views
  5. Ernest Defoe ·
    You define a friendly URL, load the page, and the address reads /discord/discord/invite/abc123. The route works, nothing errors, and the duplication looks like a typo somewhere you cannot find. It is not a typo. Invision Community prepends topLevel to every friendly path in the file. Repeat it in the path and you get it twice. Wrong { "topLevel": "discord", "pages": { "myapp_invite": { "friendly": "discord/invite/{@key}", "real": "app=myapp&modul
    • 0 comments
    • 29 views
  6. Ernest Defoe ·
    If your application's menu entry shows as menu__yourapp_settings_0 instead of its name, the shape of data/acpmenu.json is wrong — not your language file. Wrong, and it looks perfectly reasonable: { "settings": [ { "tab": "community", "controller": "settings" } ] } Right: { "settings": { "settings": { "tab": "community", "controller": "settings" } } } Why the trailing number appears The structure is { module: { item: { … } } }, and the item key becomes part of the language key — menu__&
    • 0 comments
    • 21 views
  7. Ernest Defoe ·
    You install an application and a tab appears in the AdminCP navigation called: menutab_system sitting between Community and Members, looking like a corrupted install. Nothing is logged, nothing errors, and the application otherwise works perfectly. The cause The tab value in data/acpmenu.json is never validated. Invision Community takes whatever you write, creates a tab for it, and looks up its display name from the language key menutab__<tab> — note the double underscore. If no such k
    • 0 comments
    • 26 views
  8. Ernest Defoe ·
    You add an AdminCP controller. The list screen works. Then you click Add, or Edit, or a date-range link on your own report, and Invision Community answers: Sorry, you do not have permission for that! You are logged in as a root administrator. Nothing is wrong with your ACP restrictions, and that is exactly where the message sends you to look. The cause is CSRF, not permissions IPS\Dispatcher\Admin runs this before dispatching: if ( !isset( $this->classname::$csrfProtected ) and arra
    • 0 comments
    • 43 views
  9. Ernest Defoe ·
    An application whose listeners.json or extensions.json does not parse installs perfectly, shows its AdminCP screens, saves its settings — and never runs a single line of its own automation. There is no error, no log entry, and nothing in the interface that looks wrong. The cause Core reads both manifests the same way, inside an and chain, with the warning suppressed: if ( file_exists( $jsonFile ) and $json = @json_decode( file_get_contents( $jsonFile ), TRUE ) ) { foreach( $json as $file
    • 0 comments
    • 34 views
  10. Ernest Defoe ·
    An application's versions live in data/versions.json, keyed by a long integer version and valued with the human one: { "10000": "1.0.0", "10001": "1.0.1", "10002": "1.0.2" } Uploading the same version number is silently a no-op Invision Community compares the long version in the uploaded file against the installed one. If it is not higher, the upload is accepted and nothing happens. No error, no warning, no changed files. This is the single most wasteful mistake in application de
    • 0 comments
    • 28 views
  11. Ernest Defoe ·
    Loading init.php from a CLI script gives you most of the framework, and it is by far the fastest way to test an application. Some things genuinely cannot run there, and knowing which saves a lot of time spent debugging the harness instead of the code. The basic harness <?php require_once '/var/www/html/init.php'; use IPS\Db; /* IPS installs its own error handlers. Under CLI a fatal can end the process with NO OUTPUT AT ALL, which reads as the script silently stopping. Write to a fi
    • 0 comments
    • 28 views

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.