<p>You almost certainly don't have to update the meta tags when you use AJAX to load pages like this.</p>

<p>Meta tags are not exposed to the end user; they're there for search engine crawlers and social media embedding (e.g. Facebook) etc. Crawlers will read the meta tag values from the original HTML at the URL being crawled or shared, not whatever values you update to using JavaScript in an AJAX callback.</p>

<p>On the other hand, updating the page/document title can be a good idea, as users will see this value in their browser.</p>

<p>You can update the document title simply by setting</p>

<pre><code>document.title = "Who let the dogs out?"
</code></pre>

<p>somewhere in your JavaScript. A good place to do this in regards to <a href="https://designbycosmic.com/journal/craft-cms-ajax-page-transitions-with-history-pushstate" rel="nofollow">the tutorial script you're using</a> would be inside the <code>ajaxLoad()</code> method, i.e.</p>

<pre><code>ajaxLoad = function(html) {
    init();

    /* ----- Here you could maybe add logic to set the HTML title to the new page title ----- */
    document.title = "Who let the dogs out?";

    ...
},
</code></pre>

<p>Of course, you'll want to set the document title to something relevant – preferably the "real" page title for that URL. You certainly <em>could</em> use the ElementAPI plugin to pull your entry's title, but that would mean a ton of work <em>and</em> an additional AJAX request. A much simpler way to do it is to set a data-attribute somewhere in the markup returned by the original AJAX call, e.g.:</p>

<pre><code>&lt;div class="js-ajax-wrapper" data-title="{{ siteName }}: {{ entry.title }}"&gt;
    {{ entry.body }}
    ...
&lt;/div&gt;
</code></pre>

<p>And then do something like this in your <code>ajaxLoad()</code> method:</p>

<pre><code>ajaxLoad = function(html) {
    ...
    document.title = $('&lt;div /&gt;').append(html).children('.js-ajax-wrapper').data('title');
    ...
},
</code></pre>

<p>Note that the designbycosmic.com script has a small bug – in order for the above to work you'll have to change the call to <code>ajaxLoad()</code> inside the <code>success</code> callback for the <code>loadPage()</code> method to <code>ajaxLoad(result);</code> – alternatively, you can ignore the <code>ajaxLoad()</code> method and just change the document title inside the <code>success</code> callback:</p>

<pre><code>success: function(result){
    ...
    document.title = $('.js-main .js-ajax-wrapper').data('title');
    /* ----- Bring In New Content ----- */
    ...    
},
</code></pre>

<p>Finally, as an aside your issue with the ElementAPI plugin is that you're returning a JSON payload (containing only the <code>title</code>, <code>url</code> and <code>jsonUrl</code> for the entry), yet you're attempting to inject that data into the DOM as HTML (i.e. <code>$main.html(result);</code>.</p>

CC BY-SA 3.0
2016-08-10T23:55:42.903Z
Hey there. Sorry for the late reply I am working on this project at night (I don't have any other time slot left open). 

Thanks for the detailed comment. I tried it the way you suggested and indeed it does work. 

I went for the first way and changing the ajaxLoad() to ajaxLoad(results) - it works great. Oddly when I tried it in the complete function it threw out "undefined" but I am happy as it is now. 

One more thing for the meta tags. As I said I have read a lot and I have found people using         
ga( 'send', 'pageview', ga_page );
is this necessary?
kadir
CC BY-SA 3.0
2016-08-11T00:31:51.593Z
Happy I was able to help out, @kadir. And yes, using AJAX and pushState would require manual ga.send() calls to track page views w/ Analytics. The ajaxLoad() method is a good spot for that stuff, too.
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2016-08-11T09:56:35.910Z
Thanks a lot for your help mats - Hope I will be able to show off some craftcms greatness later this year then :)
kadir
CC BY-SA 3.0
2016-08-10T07:22:18.440Z
2016-08-10T15:37:52.637Z
2016-08-10T15:37:52.637Z
Mats Mikkel Rummelhoff
<p>I have looked a lot through this StackExchange but I guess I am not too advanced in using AJAX/Json. </p>

<p>My aim is to have page transitions using Ajax. This was rather easy to accomplish following this article: 
<a href="https://designbycosmic.com/journal/craft-cms-ajax-page-transitions-with-history-pushstate" rel="nofollow">https://designbycosmic.com/journal/craft-cms-ajax-page-transitions-with-history-pushstate</a></p>

<p>Now what this article is missing out is the updating of the page title and meta tags. I have done a lot of searches and from what I understand I need to build json files for each page/entry. </p>

<p>So I installed ElementAPI and tried to get the basics working</p>

<pre><code>    &lt;?php
namespace Craft;

return [
    'endpoints' =&gt; [
        'news.json' =&gt; [
            'elementType' =&gt; 'Entry',
            'criteria' =&gt; ['section' =&gt; 'news'],
            'transformer' =&gt; function(EntryModel $entry) {
                return [
                    'title' =&gt; $entry-&gt;title,
                    'url' =&gt; $entry-&gt;url,
                    'jsonUrl' =&gt; UrlHelper::getUrl("news/{$entry-&gt;id}.json")
                ];
            },
        ]
    ]
];
</code></pre>

<p>But I am getting stuck at this point. 
I know that I can get the jquery through </p>

<pre><code>  $.ajax({
      type: 'get',
      url: 'news.json',
      data: {
        format: 'json'
      },
      success: function(result){
        $main.html(result);
      },
      error: function(){
        console.log("error.");
        location.reload();
      }
    });
</code></pre>

<p>But if I do that I am getting an empty body that loads nothing. </p>

<p>I kind of am stuck here as my knowledge ends. </p>

<p>I would be very grateful for any information on how to progress. I am really looking to understand how this works but without having at least a working model it's hard for me to analyze and reverse-engineer the code. </p>

<ajax><json>
How do I add meta data and a page title through ajax?
# How do I add meta data and a page title through ajax?

(Asked by: username_0 on 2016-08-10)

I have looked a lot through this StackExchange but I guess I am not too advanced in using AJAX/Json. 
My aim is to have page transitions using Ajax. This was rather easy to accomplish following this article: 
https://designbycosmic.com/journal/craft-cms-ajax-page-transitions-with-history-pushstate
Now what this article is missing out is the updating of the page title and meta tags. I have done a lot of searches and from what I understand I need to build json files for each page/entry. 
So I installed ElementAPI and tried to get the basics working
     [
        'news.json' => [
            'elementType' => 'Entry',
            'criteria' => ['section' => 'news'],
            'transformer' => function(EntryModel $entry) {
                return [
                    'title' => $entry->title,
                    'url' => $entry->url,
                    'jsonUrl' => UrlHelper::getUrl("news/{$entry->id}.json")
                ];
            },
        ]
    ]
];

But I am getting stuck at this point. 
I know that I can get the jquery through 
  $.ajax({
      type: 'get',
      url: 'news.json',
      data: {
        format: 'json'
      },
      success: function(result){
        $main.html(result);
      },
      error: function(){
        console.log("error.");
        location.reload();
      }
    });

But if I do that I am getting an empty body that loads nothing. 
I kind of am stuck here as my knowledge ends. 
I would be very grateful for any information on how to progress. I am really looking to understand how this works but without having at least a working model it's hard for me to analyze and reverse-engineer the code.

**Tags:** ajax, json


---

## 1 answers

### Answer by username_1 on 2016-08-10. Score: 3 | Accepted answer

You almost certainly don't have to update the meta tags when you use AJAX to load pages like this.
Meta tags are not exposed to the end user; they're there for search engine crawlers and social media embedding (e.g. Facebook) etc. Crawlers will read the meta tag values from the original HTML at the URL being crawled or shared, not whatever values you update to using JavaScript in an AJAX callback.
On the other hand, updating the page/document title can be a good idea, as users will see this value in their browser.
You can update the document title simply by setting
document.title = "Who let the dogs out?"

somewhere in your JavaScript. A good place to do this in regards to the tutorial script you're using would be inside the ajaxLoad() method, i.e.
ajaxLoad = function(html) {
    init();

    /* ----- Here you could maybe add logic to set the HTML title to the new page title ----- */
    document.title = "Who let the dogs out?";

    ...
},

Of course, you'll want to set the document title to something relevant – preferably the "real" page title for that URL. You certainly could use the ElementAPI plugin to pull your entry's title, but that would mean a ton of work and an additional AJAX request. A much simpler way to do it is to set a data-attribute somewhere in the markup returned by the original AJAX call, e.g.:

    {{ entry.body }}
    ...


And then do something like this in your ajaxLoad() method:
ajaxLoad = function(html) {
    ...
    document.title = $('').append(html).children('.js-ajax-wrapper').data('title');
    ...
},

Note that the designbycosmic.com script has a small bug – in order for the above to work you'll have to change the call to ajaxLoad() inside the success callback for the loadPage() method to ajaxLoad(result); – alternatively, you can ignore the ajaxLoad() method and just change the document title inside the success callback:
success: function(result){
    ...
    document.title = $('.js-main .js-ajax-wrapper').data('title');
    /* ----- Bring In New Content ----- */
    ...    
},

Finally, as an aside your issue with the ElementAPI plugin is that you're returning a JSON payload (containing only the title, url and jsonUrl for the entry), yet you're attempting to inject that data into the DOM as HTML (i.e. $main.html(result);.

> **Comments:**
> **username_0**: Hey there. Sorry for the late reply I am working on this project at night (I don't have any other time slot left open).   Thanks for the detailed comment. I tried it the way you suggested and indeed it does work.   I went for the first way and changing the ajaxLoad() to ajaxLoad(results) - it works great. Oddly when I tried it in the complete function it threw out "undefined" but I am happy as it is now.   One more thing for the meta tags. As I said I have read a lot and I have found people using          ga( 'send', 'pageview', ga_page ); is this necessary?  
> **username_1**: Happy I was able to help out, @username_0. And yes, using AJAX and pushState would require manual ga.send() calls to track page views w/ Analytics. The ajaxLoad() method is a good spot for that stuff, too.  
> **username_0**: Thanks a lot for your help mats - Hope I will be able to show off some craftcms greatness later this year then :)  

---

