Ajax Load more Posts On my blog i need a load more button on the bottom of each section that simply loads more posts when clicked. Everything i look at people are using other javascript libraries. I just want to use ajax no external libraries

{% for entry in craft.entries.section('news').limit(10) %}
{% set categories = craft.categories.relatedTo(entry) %}
&lt;div class="article-container"&gt;
&lt;hr /&gt;
&lt;div class="row"&gt;
    &lt;div class="col-lg-4"&gt;
        &lt;div class="article-featured-image"&gt;
            {% for asset in entry.newsFeaturedImage %}
                 &lt;img src="{{ asset.url }}" alt="{{ asset.title }}" class="mx-auto d-block img-fluid"&gt;
            {% endfor %}
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="col-lg-8"&gt;
        &lt;div class="article-meta"&gt;
            {% for category in categories %}
                &lt;small class="hl-heading-yellow"&gt;
                    &lt;span&gt;{{ category.title }}&lt;/span&gt;
                &lt;/small&gt;
            {% endfor %}
            &lt;div class="article-title"&gt;
                &lt;span&gt;{{entry.title}}&lt;/span&gt;
            &lt;/div&gt;
            &lt;div class="article-excerpt"&gt;
                {{ entry.newsExcerpt|length &gt; 150 ? entry.newsExcerpt|slice(0, 150) ~ '...' : entry.newsExcerpt  }}
            &lt;/div&gt;
            &lt;div class="article-url"&gt;
                &lt;a href="{{entry.url}}" class="dark-btn"&gt;Continue Reading&lt;/a&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
   &lt;/div&gt;
 &lt;/div&gt;
   {% endfor %}
First you create a function to send the data to a custom controller

var offset = 10
var getElements = function(){
    var data = new FormData();
    data.append('offset', offset);
    data.append('action', 'plugin-name/controller-name/function-name);
    data.append(window.csrfTokenName, window.csrfToken);

    var xhr = new XMLHttpRequest();
    xhr.open('POST', '', true);
    xhr.onload = function () {
        // check for errors
        if(this.status === 200){
            var response = {};
            try {
                response = JSON.parse(this.responseText);
            } catch(error) {
                throw Error("server did not return valid JSON: " + this.statusText + ' ' + this.status);
                return false;
            }
            // append your response to the object/container you like
            offset += response.elements;
        }
    }
    xhr.send(data);
}


Then in your controller just fetch the entries

public function actionGetElements(): Response
{
    $offset = Craft::$app-&gt;getRequest()-&gt;getBodyParam('offset');
    $query = Entry::find()-&gt;section(['whatever'])-&gt;limit(10)-&gt;offset($offset);
    $elements = $query-&gt;all();
    $html = Craft::$app-&gt;getView()-&gt;renderTemplate('path/to/template', [
        'elements' =&gt; $elements
    ]);
    $fetchedElements = \count($elements);
    $totalElements = $query-&gt;count();
    return $this-&gt;asJson(
        [
            'html' =&gt; $html,
            'success' =&gt; true,
            'elements' =&gt; $fetchedElements,
            // check if the number of fetched element + offset is equal to the number of total elements
            // if that's the case you can hide the button to load more since there are no more elements
            'hideButton' =&gt; $fetchedElements + $offset === $totalElements
        ]
    );
}


Keep in mind to include a CSRF token data.append(window.csrfTokenName, window.csrfToken); and to include an protected $allowAnonymous = [ 'actionGetElements']; to your controller