Both the YouTube and Facebook feed shortcodes support loading additional content dynamically via AJAX, so visitors can paginate through posts or videos without a full page refresh. Every AJAX call is authenticated with a WordPress nonce validated server-side before any data is fetched or returned. API credentials are never exposed to the browser.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Jhon-mantila/pluging-wordpress/llms.txt
Use this file to discover all available pages before exploring further.
YouTube AJAX Loading
The YouTube feed’s AJAX loading is triggered when a visitor clicks the “Cargar más videos” button. This button is only rendered when the shortcode’smax attribute is set to all (or 0), which puts the feed into unlimited mode. For all fixed max values, videos are rendered entirely server-side on the initial page load and no “load more” button appears.
Session Model
To prevent the YouTube API key from ever appearing in the browser, the plugin creates a server-side session at render time:- A UUID is generated with
wp_generate_uuid4(). - The session data (
api_key,channel_id,mode) is stored in a WordPress transient keyed asesquina_yt_s_{uuid}with a 1-hour TTL. - Only the UUID is sent to the browser (embedded in the feed’s
data-configattribute). - The set of already-seen video IDs is stored separately under
esquina_yt_seen_{uuid}(also 1 hour TTL) so duplicate videos are never returned across paginated requests.
AJAX Request
When the user clicks “Cargar más videos”, the frontend JavaScript (youtube-feed.js) posts to admin-ajax.php:
| Parameter | Description |
|---|---|
action | esquina_yt_more |
nonce | WordPress nonce created with wp_create_nonce('esquina_yt_feed') |
session | The UUID session ID from data-config |
page_token | The YouTube playlist nextPageToken from the previous response |
batch | Number of videos to load (mirrors the batch shortcode attribute) |
AJAX Response
The server validates the nonce, looks up the session transient to retrieve the API key, fetches the next batch from the YouTube playlist, updates the seen-IDs transient, and returns:html field contains pre-rendered card markup that is directly appended to the feed’s .esquina-yt__rail container. Each new card is then bound to the same hover-preview and click-to-modal event listeners.
WordPress Hooks
Facebook AJAX Loading
The Facebook feed always loads the first page of posts server-side at render time. When the user navigates past the last post available in the locally cached set, the frontend JavaScript (facebook-posts.js) automatically fetches the next page from the server before rendering.
Pagination Model
The Facebook Graph API uses cursor-based pagination. The initial server-side render passes the firstafter cursor (from the Graph API response) into the feed’s data-config attribute. The JavaScript state machine tracks pageOffset and nextCursor client-side. When advancing past the locally available posts, fetchMore() is called automatically before rendering.
AJAX Request
The client posts toadmin-ajax.php when it needs more posts:
| Parameter | Description |
|---|---|
action | esquina_fb_more |
nonce | WordPress nonce created with wp_create_nonce('esquina_fb_feed') |
page_id | The Facebook Page ID |
limit | Number of posts to request from the Graph API |
after | The cursor string from the previous API response |
AJAX Response
The server validates the nonce, reads the access token from the saved option (never from the client request), calls the Graph API with theafter cursor, and returns:
posts array contains normalised post objects. The next_cursor value is stored in the JavaScript state and used for subsequent requests.
WordPress Hooks
Security Model
Both AJAX handlers follow the same security pattern:Nonce validation
Every handler calls
check_ajax_referer() as its very first action. If the nonce is missing or invalid, WordPress terminates the request immediately with a 403 response before any processing occurs.Input sanitisation
All
$_POST values are sanitised before use: sanitize_text_field() for strings, intval() for integers, and regex stripping for numeric IDs.Credentials stay server-side
YouTube: The API key is stored in the session transient under a UUID known only to the server. The browser only ever holds the UUID. Even if the session UUID were intercepted, it cannot be used to retrieve the raw API key.Facebook: The Page Access Token is read from
wp_options on the server during each AJAX request. It is never included in the JSON payload returned to the client.When AJAX Is Not Used
AJAX loading is only activated for the YouTube feed when
max="all" (or max="0") is set. For any fixed numeric max value, all videos are fetched and rendered server-side at page load — the “Cargar más videos” button is never output and no JavaScript requests are made.The Facebook feed always uses AJAX for pages beyond the first: the initial posts are rendered server-side, but every subsequent page navigation that exhausts the locally held posts triggers an AJAX fetch.Related Pages
Caching
How transients reduce API calls for both YouTube and Facebook feeds.
YouTube Largo Shortcode
Full reference for the
[youtube_largo] shortcode, including the max and batch attributes.Facebook Posts Shortcode
Full reference for the
[facebook_posts] shortcode and its pagination settings.Security Best Practices
Further guidance on protecting API credentials in WordPress.