I'm trying to do an ajax request from my themes header.php file. I've read that I have to use the admin-ajax.php file to achieve this. So I looked for examples and found this one.

My code in the header.php file looks like this:

    $('.test a').click(function(){
        var className = $(this).attr('class');

            url: "<?php echo admin_url('admin-ajax.php'); ?>",
            data: {
                'action': 'myFunc',
                'id': className
            success: function(res){
            error: function(err){
                alert("Error: " + err);

And my PHP code looks like this:

function myFunc() {
    echo "hello";

add_action('wp_ajax_nopriv_myFunc', 'myFunc');

I'm not sure where I should put this PHP code. Should I put this in my functions.php file or directly to the admin-ajax.php file? It doesn't matter where I put the PHP code, the output is always 0 (the last line in admin-ajax.php is die('0')). Or is it because of my url parameter?

  • Have you considered using a REST API endpoint instead?
    – Tom J Nowell
    Commented May 25, 2017 at 16:16
  • I'm not sure what you mean and how a REST API could help to solve my problem. Can you please give me an example?
    – Roman
    Commented May 25, 2017 at 16:19
  • Make sure you're logged out when testing the nopriv case.
    – birgire
    Commented May 25, 2017 at 16:29
  • @birgire I tested it with nopriv and without. Both of them doesn't work.
    – Roman
    Commented May 25, 2017 at 16:31
  • 1
    @Roman REST API endpoints are more structured and easier to work with, fewer pitfalls, and fewer steps to implement. The javascript part works the same, but the PHP part is simpler and more straight forward
    – Tom J Nowell
    Commented May 25, 2017 at 21:41

1 Answer 1


Your custom functions should always go in your theme's functions.php file (if they are not within plugin territory). You should never try to modify any core files outside the wp-content folder (except wp-config.php) as they will be overridden by future updates.

Now, there are 2 ways to do what you want.

1 - Admin-ajax

This simple function will serve you nice to get a hello! as an output:

add_action('wp_ajax_my_ajax_handler', 'my_ajax_handler');
add_action('wp_ajax_nopriv_my_ajax_handler', 'my_ajax_handler');
function my_ajax_handler (){

Now, try and access the admin-ajax.php directly to see if you have an answer, by visiting wp-admin/admin-ajax.php?action=my_ajax_handler. This should work for both logged-in and non-logged-in users.


Even simpler. Take a look into this:

add_action( 'rest_api_init', function () {
    //Path to ajax function
    register_rest_route( 'Roman/v1', '/say_hello/', array(
            'methods' => 'GET', 
            'callback' => 'my_hello_function' 
    ) );

And a function to say hello:

function my_hello_function(){
    return __('Hello!','text-domain');

Now, if you send a request to http://example.com/wp-json/Roman/v1/say_hello/, you will get a nice welcome as JSON, like:


Which you can use in your jQuery script.

  • Thank you for your suggestions, I'll try them both. For the first way, should I put this function my_ajax_handler() into functions.php as you said, right? And what about my ajax request in header.php? Should I there request wp-admin/admin-ajax.php?action=my_ajax_handler in the url parameter?
    – Roman
    Commented May 25, 2017 at 18:14
  • Okay I tested both and both works fine! I've seen that I just missed the ?action= part in my request url. And I also had to move the function to functions.php. Thank you very much :)
    – Roman
    Commented May 25, 2017 at 18:23
  • 1
    @Roman You are welcome. It seems you already figured it out yourself! nice. And yes, it all goes in functions.php. By the way, @TomJNowell really loves REST API, that's why he always recommends this over admin-ajax!
    – Johansson
    Commented May 25, 2017 at 18:25
  • 1
    REST APIs are cool and very easy to use and I used it a few times for other projects, but I didn't know how to implement it in my case here.
    – Roman
    Commented May 25, 2017 at 18:41

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.