I see the problem now. It seems weird that ProcessController::isAjax() even exists, tbh. It may be vestigial and can be replaced by $config->ajax, which you could then override yourself in ready.php. But maybe it’s got some vital purpose. I’d say, open an issue about it on Github.
Some other options you can implement right now without hacking the core:
Just die()
public function ___executeCount() {
$count = (int)$this->input->post('count');
die($this->renderCountButton(++$count));
}
Instead of returning markup from your execute() method, just terminate the request with your desired output. This will skip things like finished.php, so that’s something to be aware of, but it’s probably fine.
Just add X-Requested-With
public function ___execute() {
$this->config->scripts->add('https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js');
return <<<HTML
<div hx-headers='{"X-Requested-With": "XMLHttpRequest"}'>
<h2>Hello.</h2>
{$this->renderCountButton(0)}
</div>
HTML;
}
public function ___executeCount() {
$count = (int)$this->input->post('count');
return $this->renderCountButton(++$count);
}
Make HTMX send the X-Requested-With header. Now you're an ajax request according to ProcessWire. The attribute is inherited, so you can just set it once and forget about it, as in the above example.
I have attached a complete module that minimally demonstrates the issue.
ProcessHtmxTest.module