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.

Background work and scheduled tasks

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

5 Articles in this category

  1. Ernest Defoe ·
    A WebSocket gateway that fans Invision Community events out to browsers usually authenticates the connection — a short-lived token, signed with a shared secret, proves the socket came from a page your community served. That is enough while every channel is public, like a forum topic. The moment a channel carries something private — a conversation between two members — it is not enough, because the token says who the member is but not which channels they are allowed to join. Nothing stops a logge
    • 0 comments
    • 25 views
  2. Ernest Defoe ·
    An Invision Community site that has not been given a cron job runs its scheduled tasks during ordinary page views. That is the default, and most self-hosted communities never change it. If your application does anything slow in a queue or a task — and calling an outside API is slow — a random visitor pays for it with their page load, and with the database connection that page load is holding. This is not a theoretical concern. It took a live community down. The symptom The report to look o
    • 0 comments
    • 20 views
  3. Ernest Defoe ·
    You write a reporting query, wrap it in try / catch so a bad query can never take down an AdminCP page, and ship it. The screen renders. The table is empty. You conclude there is no data yet. There is data. The query is broken, and your own catch is what turned a fault into a plausible-looking zero. The query Db::i()->select( 'conv_title, conv_url, conv_class, conv_item, COUNT(*) AS joined', 'my_table', array( 'conv_item > 0' ), 'joined DESC', 25, array( 'conv_c
    • 0 comments
    • 33 views
  4. Ernest Defoe ·
    Some work has to happen on every page view — recording an analytic, touching a cache, noting that something was seen — and none of it should make the visitor wait. Invision Community supports this, but the pieces are not obvious and the method that looks right is the wrong one. core/Loader is the only per-request extension point Dispatcher\Front invokes exactly one extension point on every front-end request, and it invokes it three times: // early, while building the page foreach ( Applicati
    • 0 comments
    • 36 views
  5. Ernest Defoe ·
    A core/Queue extension is a resumable batch job. You register it in your app's data/extensions.json, hand it work with IPS\Task::queue(), and core writes one row into core_queue. The queue task (IPS\core\tasks\queue) then calls IPS\Task::runQueue() in a loop until it runs out of time, memory, or rows — each call picks one row, instantiates your class, and calls run() exactly once. There are only three consumers in the whole suite, and it is worth knowing all three because they behave different
    • 0 comments
    • 36 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.