I'm building a plugin, and it all worked just fine until I decided to change the front-end form submission to use AJAX instead of submitting directly. I have a form on the front-end with this action:

<form class="gtPoll__form" method="post" accept-charset="UTF-8" action="">
      <input type="hidden" name="action" value="gtPoll/poll/incrementAnswer"> 

and a controller at /craft/plugins/controllers/GtPoll_PollController.php with the method actionIncrementAnswer(). I also have the line

protected $allowAnonymous = array('actionIncrementAnswer');

in this controller class.

When I submit that form via AJAX on the front-end (to the URL in the action value), I get a 404 and the rest of my JavaScript breaks, but the controller action DOES complete and the answer count is incremented properly.

If I add this code to my main plugin file:

public function registerSiteRoutes()
        return array(
            'gtPoll/poll/incrementAnswer' => array( 'action' => 'gtPoll/poll/incrementAnswer')

Then I don't get the 404 and my JavaScript all works, but the controller action occurs twice each time the AJAX call is made, so my answer count is doubly incremented.

I'm not really sure what's going on. I also tried using

{{ actionUrl('gtPoll/poll/incrementAnswer') }}

in the hidden action field, but that doesn't work at all.

What's the correct way to access this controller action from the front-end?

Thanks in advance!

2 Answers 2


Rather than submitting the form, try hitting it with the Craft JS object. Per the docs:

var data = {
    // ...

Craft.postActionRequest('cocktailRecipes/ingredients/saveIngredient', data, function(response) {
    // ...



Found the solution here: Controller action works but still gives 404

I wasn't returning JSON in the controller, so Craft was trying to complete the request and getting a 404.

I ended up removing the registerSiteRoutes method from the main plugin class and changing the action field value to:

{{ actionUrl('gtPoll/poll/incrementAnswer') }}

and that now works correctly!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.