A Hopper is “a curated list of source URLs on a topic, plus a scheduled brief from them”. This guide walks through setting one up end-to-end, from creating the Hopper to seeing the first article published unattended.
Hopper is a Premium-tier feature. Trial and Standard tiers see the menu hidden. This guide assumes you're on Premium or Enterprise.
Contents
The Hopper concept
A Hopper has three moving parts:
1. A topic + watch source
Name, description, keywords. Plus a watch: a Search query, an RSS feed URL, or a fixed URL set. The watch is what gets harvested when you click Generate / Refresh candidates.
2. A curated list of sources
The Candidates tab. Each harvested URL is fetched and verified — the page body has to actually mention the words from the search snippet, or the row is marked Bad. You curate: Mark good / Mark bad / Delete. The Good rows are the Hopper's source list.
3. A cadence
Manual (Run Now from the tab), or daily / 3x weekly / 2x weekly / weekly with a time of day in your site timezone. Each cadence cycle produces ONE brief whose sources are every Good URL.
What the Hopper produces is briefs — one brief per cycle. The article-gen pipeline then runs on each brief the same way it runs on a one-off. Optional Auto-generate and Auto-publish settings make the whole loop unattended.
Step 1 — Create a Hopper
- Go to Components > Article Generator > Hoppers and click New.
- Topic tab — fill in:
- Name — the editorial label, e.g. “UK politics — Andy Burnham”.
- Description — a short topic frame the AI uses when synthesising the brief title. Keep it crisp.
- Keywords — comma-separated. Inherited by every brief this Hopper emits.
- Always-include source URLs — URLs that ride on every emitted brief alongside whatever the watch finds. Leave empty for most cases.
- Authoritative sources for this topic — per-Hopper authoritative-domain hints (e.g.
bbc.co.uk,nature.com). Sub-domains match. Used to prefer publisher-grade results in the candidate cluster step.
- Editorial Defaults tab — tone, reading level, target word count, content structure, citation mode, banner icon, banner theme. These ride on every brief the Hopper emits, so you set them once.
- Production tab — the watch + cadence:
- What to watch — Search query / RSS feed / URL set.
- Watch value — the actual query / feed URL / URL list.
- Search query: the words you'd type into Google. Hopper expands this internally with “latest news” / “this week” time-bias variants, plus a Serper news-endpoint variant if Serper is your provider.
- RSS feed: a single
http(s)://URL. RSS 2.0 and Atom 1.0 both supported. - URL set: one URL per line, up to 20. Each URL becomes one candidate.
- Cadence — Manual, Daily, 3x weekly, 2x weekly, or Weekly. Manual fires only from the Run Now button on the Candidates tab; the rest are driven by the scheduled task.
- Time of day — shown when cadence is non-manual. Site-timezone HH:MM at which the cadence fires. Daily fires AT that time each day; weekly variants use it as a not-before floor on the gap.
- Articles per run — left as 1 for the simplified Hopper model.
- Monthly cap — soft self-imposed ceiling on briefs per month. 0 = unlimited (your tier's monthly article cap still applies).
- Approval mode — Manual = emitted briefs land as drafts for your review; Auto = published immediately as drafts ready for the tick pipeline.
- Auto-generate articles — off by default. See Auto-generate & auto-publish below.
- Final article state — shown when Auto-generate is on. Draft (you review before publishing) or Published (live immediately).
- Click Save & Close. The Hopper appears in the list.
Step 2 — Generate & curate candidates
Open the Hopper you just created and switch to the Candidates tab.
Generate the first batch
On a brand-new Hopper the tab shows a centred “No candidates yet” card with a Generate candidates button. Click it. What happens behind the scenes:
- Harvest — the watch type is dispatched. Search queries hit your configured search provider (Serper / Tavily / Google); RSS feeds are fetched and parsed; URL sets are fetched directly. Search queries also try a Serper news endpoint variant for journalist sources.
- Dedupe — URLs are deduped by host+path so the same article doesn't enter twice.
- Inline verification — each candidate URL is fetched (5s timeout per URL, 45s overall budget) and the body checked. The verifier requires the page to actually load, be long enough to be a real article, and contain at least 2 keywords drawn from the search title+snippet. URLs that fail are marked Bad. URLs whose verification timed out are marked Unverified.
- Persist — rows land in the Candidates tab already badged Good / Bad / Unverified.
The Run Now message after harvest tells you the breakdown: e.g. “Ran 1 Hopper(s) — 21 new candidate(s) found, 1 brief(s) emitted. (3 source(s) dropped by inline verifier — see the Candidates tab.)”
Curate the list
Each row carries a Status badge:
- Good — in the source list. Every Run Now / scheduled run uses this URL as a source.
- Bad — excluded. Verifier dropped it (or admin marked it Bad). The row stays so you can audit.
- Unverified — harvest budget ran out before checking. Click Verify on the toolbar to clear the residue.
Toolbar buttons:
- Run Now — produce ONE brief from the current Good list. See the next section.
- Refresh candidates — harvest again. Duplicates skip on signature; new URLs land verified.
- Create brief from selected sources — tick rows then click. Literal selection, no filter. One brief with exactly the URLs you ticked as sources.
- Always include — promotes the URLs of selected rows to the Hopper's default-sources list, so every future emitted brief inherits them.
- Mark good / Mark bad — admin override on the verifier verdict. Use when you know the URL is good but the verifier was over-strict (or vice-versa).
- Delete — hard delete of the row. Confirmation appears inline (Joomla framework dialog — no browser modals). The URL signature is kept, so a future Refresh could rediscover the URL.
- Verify (N) — runs the verifier across Unverified rows. Visible only when there are unverified rows to act on.
Click row titles to open the source URL in a new tab. Hover the snippet for the full text.
Step 3 — Run Now: the first brief
When you have at least one Good row, click Run Now on the Candidates tab.
The Hopper:
- Loads every Good row's URL.
- Calls the AI to synthesise a title, topic statement, and keyword list from the cluster.
- Creates ONE brief whose sources field includes those URLs plus the Hopper's Always-include source URLs.
- Stamps the Hopper's last_run so the cadence doesn't fire again immediately.
- Redirects you to the new brief's edit screen.
From there, click Generate Article on the brief's toolbar to run the article-gen pipeline. The pipeline researches across all the source URLs and writes a piece that cross-references them — not a paraphrase of any single source.
- All rows are Unverified — click Verify first.
- All rows are Bad — use Mark good on any you trust, or refresh candidates with a better watch value.
- The Hopper has just been created and you haven't generated candidates yet.
Step 4 — Cadence & time of day
Manual cadence (the default) is fine for one-off topics. For ongoing coverage, set a cadence and a time of day.
Cadence options
| Cadence | Minimum gap | Runs per 7d |
|---|---|---|
| Daily | 23 hours | 7 |
| 3x weekly | 55 hours | 3 |
| 2x weekly | 83 hours | 2 |
| Weekly | 167 hours | 1 |
How the time of day works
The time-of-day field is the “earliest the Hopper becomes eligible to fire today”. The scheduled task checks each Hopper on every tick:
- If today's site-timezone clock hasn't reached the configured HH:MM, the Hopper isn't due. Wait.
- Once the time of day has passed AND the last run is older than the cadence's minimum gap, the Hopper fires on that tick.
So a Hopper set to Daily at 02:00:
- The 01:00 cron tick: not due (haven't reached today's 02:00 target yet).
- The 02:00 cron tick: due (we're at the target and last run was ≥23h ago). Fires.
- The 02:05 cron tick: not due (just ran, <23h gap).
If your cron runs less frequently than the time-of-day target — say once daily at 05:00 — the 02:00 Hopper still fires at 05:00 (it's the next tick after the target). The cadence drift problem of pure gap-based scheduling is gone, but you do still need the scheduled task to be running often enough to actually hit your target window.
Step 5 — Scheduled task setup
The unified Article Generator scheduled task drives every Hopper's cadence (plus on-demand batch jobs and the unattended generation phases). Create it once and leave it running.
Create the task
- Go to System > Scheduled Tasks > New.
- Pick task type Article Generator.
- Give it a name (e.g. “Article Generator”).
- On the Execution Rule tab, choose Interval, in minutes, set to 5. This is the recommended cadence: it keeps the Hopper time-of-day accurate to within 5 minutes, and the auto-generate phase ticks the article-gen pipeline forward 20 briefs per run.
- On the Options tab, set Status to Enabled.
- Save.
What the task does on each tick
- Hopper discovery (30s budget) — runs every Hopper whose cadence is due. Calls produceBriefs; new briefs land as drafts (or as state=1 if the Hopper's Approval mode is Auto).
- Auto-generation (90s budget, max 20 briefs) — for briefs whose Hopper has Auto-generate articles on, ticks the article-gen pipeline forward one step. The same step machine the browser drives, headless. A brief that takes 5 ticks to finish will progress one step per scheduled tick.
- Auto-publish (30s budget) — briefs that finished generation with Final article state = Published get their Joomla article flipped to state=1.
- Batch queue (30s budget) — services on-demand jobs from the Generate All Steps button.
artigen.batch_queue, artigen.news_beat, or artigen.hopper_sweep — delete them and create one with the new Article Generator type. The old type strings don't resolve any more.Logs
Each task's log lives at administrator/logs/task_{id}.log.php. Phase-level events also mirror to administrator/logs/com_artigen.error.php. A healthy run looks like:
2026-06-25T02:05:01+00:00 INFO task9 Running task#09 'Article Generator'. 2026-06-25T02:05:01+00:00 INFO task9 Task> Hopper #1 "AI ethics watch": 4 source(s) used, 1 brief(s) emitted 2026-06-25T02:05:01+00:00 INFO task9 Task> Hopper discovery phase: 3 due, ran 1, skipped 2 (not yet due) 2026-06-25T02:05:02+00:00 INFO task9 Task> Auto-generation phase: ticked 1 brief(s), 0 completed, 0 failed 2026-06-25T02:05:02+00:00 INFO task9 Task> Auto-publish phase — no completed briefs awaiting publish 2026-06-25T02:05:02+00:00 INFO task9 Task> Batch queue phase — no pending batch jobs 2026-06-25T02:05:02+00:00 INFO task9 Successfully finished task#09 in 0.14 seconds.
Step 6 — Auto-generate & auto-publish (optional)
If you want the loop fully unattended, switch on the two automation knobs on the Hopper edit form (Production tab):
- Auto-generate articles — when on, briefs this Hopper emits are picked up by the scheduled task's auto-generation phase. Each cron tick advances a brief one step. A typical article finishes in 5–7 ticks (5 to 35 minutes wall-clock at the recommended 5-minute cadence).
- Final article state —
- Draft — article generates fully but stays unpublished. You review and click Publish in Joomla's article editor. Recommended for new Hoppers.
- Published — article goes live as soon as the pipeline completes. Use only when you trust the Hopper's source curation completely; the article never gets a human review pass.
Briefs inherit the Hopper's auto_publish_state at emit time, so changing the Hopper's setting only affects briefs emitted from that point on. Previously-emitted briefs keep whatever was set when they were created.
Troubleshooting
Three things have to be true:
- The Article Generator scheduled task exists, is enabled, and is set to run at least as often as the Hopper's Time of day requires.
- The Hopper's Time of day is in your site timezone (the value you typed in the field). If your scheduled task only runs once a day at, say, 09:00, a Hopper set to fire at 02:00 will fire at 09:00 — not 02:00.
- The Hopper has at least one Good candidate row. Run Now and the cadence both use the same Good-rows pool.
Pre-3.5.66 Hoppers used pure gap-based scheduling (24h since last run), which silently drifted each day. If you upgraded from earlier, the migration set every Hopper's Time of day to 02:00; edit and change as needed.
cadence_time column was VARCHAR(5) but browsers (Safari for one) submit <input type="time"> as HH:MM:SS. Upgrade to 3.5.67 or later — the column widens to VARCHAR(8) automatically via the migration + postflight ensure helper.Common causes:
- Search query Hoppers — no search provider configured. Check Components > Article Generator > Options > Search Provider. Serper is the recommended provider.
- Search query Hoppers — the query is too narrow or the configured Excluded source domains blocklist is stripping every result. Check
com_artigen.error.phpfor per-variant log lines. - RSS feed Hoppers — the feed URL returns HTML or a non-XML body. The verifier surfaces “RSS XML parse failed”.
- URL set Hoppers — URLs aren't
http(s)://prefixed, or the watch_value is blank.
Check, in order:
- The Hopper has Auto-generate articles set to On.
- The brief was emitted AFTER you flipped Auto-generate on (it's inherited at emit time, not retroactively).
- The brief's pipeline_state is
idleorrunning. Open the brief and check the Status stepper — if it'sfailedorcancelled, the auto phase skips it. Click Regenerate to reset. - The scheduled task is running. Check the task's last-run timestamp on System > Scheduled Tasks.
published AND its pipeline_state needs to be completed. Open the brief and check both. Briefs emitted before you set Final article state to Published won't auto-publish — manually publish them in Joomla's article editor or regenerate to inherit the new value.Full documentation index: Article Generator documentation. Changelog: artigen-changelog.html.