SDAweb Social Galleri Feed

Descrição

SDAweb Social Galleri Feed connects to the Instagram Graph API and displays your posts in a customizable grid gallery with lightbox. Supports multiple Instagram accounts — connect up to 20 accounts and display different feeds on different pages. Built for speed — feeds load instantly on cached pages with zero network requests.

Features

Multi-Account Support
* Connect up to 20 Instagram accounts, each with its own token and cache
* Per-account test connection, cache management, and failure tracking
* Display different accounts on different pages with the account shortcode attribute
* Visual Shortcode Builder shows which account you’re building for

Layout & Design
* Multiple layouts — Grid, masonry, and highlight modes
* Responsive columns — Separate settings for desktop, laptop, tablet, and mobile
* Profile header — Avatar, username, follower count, bio, and follow button
* Hover effects — Overlay on image hover with gradient
* Color pickers — Customize likes icon, comments icon, and date text colors

Instagram Stories
* Story ring — Gradient ring on avatar when Stories are active (like Instagram)
* Fullscreen Story viewer — Auto-advance, tap navigation, progress bars, keyboard support
* Video Stories play automatically (muted by default)
* Per-account Stories refresh every 15 minutes via WP-Cron
* Toggle on/off globally or per shortcode

Lightbox
* Fullscreen lightbox — Carousel navigation with keyboard and swipe support
* Swipe-up-to-close — Mobile-native gesture
* Engagement stats — Likes, comments, media type badge, and relative date

Content & Filtering
* Multiple feeds — Use feed_id attribute for independent feeds on different pages
* Hashtag filtering — Include or exclude posts by hashtag
* Media type filter — Filter by image, video, or carousel
* Load more — Paginated loading with customizable button

Performance
* Instant loading — The first screens are built into the page, zero network requests on cache hit
* REST API endpoint with legacy AJAX fallback
* Stale-while-revalidate — Expired cache served instantly while refreshing
* Per-account WP-Cron background refresh — All caches stay warm automatically
* Lean pages — Only the posts a page can show are built into it; Load more fetches the rest on demand
* Lazy loading and incremental grid rendering
* Per-IP rate limiting

Localization
* All 30+ frontend strings configurable in admin (translated defaults, override any of them)
* Relative timestamps and month names customizable

Security
* Bearer token authentication — API token sent via Authorization header
* AES-256-CBC token encryption at rest with random IV per encryption
* CSRF protection — check_admin_referer() on all admin actions
* XSS prevention — gallery built with DOM methods, all output escaped
* Clean uninstall — Removes all options, transients, and cron jobs per account

Accessibility
* Full keyboard navigation in lightbox and gallery
* ARIA labels and screen reader support
* Respects prefers-reduced-motion

Shortcode

[sdawsoga_gallery]

Shortcode Attributes

  • account — Account slug from Accounts tab (default: default account)
  • feed_id — Gallery name for CSS targeting
  • limit — Number of posts to display (default: 9)
  • columns — Number of columns (default: 3)
  • layout — grid, masonry, or highlight
  • aspect_ratio — square, portrait, instagram, or original
  • padding — Gap between images in pixels
  • show_header — Show/hide profile header (true/false)
  • show_loadmore — Show/hide load more button (true/false)
  • hover_effect — Enable/disable hover overlay (true/false)
  • filter_type — all, image, video, or carousel
  • hashtag — Only show posts containing this hashtag
  • exclude_hashtags — Comma-separated hashtags to exclude
  • show_stories — Show/hide Instagram Stories ring (true/false)

Requirements

  • A Facebook Page connected to an Instagram Business or Creator account
  • A valid Facebook Page Access Token with the instagram_basic, pages_show_list, pages_read_engagement, and instagram_manage_insights permissions (all four are required for the feed)
  • PHP 7.4+ and WordPress 5.8+

Third-Party Services

This plugin connects to the Instagram Graph API (via Facebook) to retrieve your Instagram posts, profile information, and engagement metrics.

When data is sent: When the plugin refreshes the feed cache — by the WP-Cron background refresh, by “Refresh now” or a settings change in the admin panel, or when a visitor opens a gallery page while the cache is empty. With default settings, this happens approximately once per hour.

What data is sent: Your Facebook Page Access Token and Instagram Business Account ID are sent to Facebook’s servers to authenticate and retrieve your posts. No visitor information is included in these requests.

Pictures and videos are loaded by the visitor’s browser directly from Instagram’s media servers (cdninstagram.com and fbcdn.net, operated by Meta), as with any embedded Instagram content. Meta therefore receives the visitor’s IP address and browser details for those image requests, under the privacy policy linked above. The plugin itself does not track visitors and sets no cookies. A suggested privacy-policy text is provided under Settings Privacy Policy Guide.

Capturas de tela

Blocos

Este plugin disponibiliza 1 bloco.

  • Social Galleri Feed Display your Instagram feed as a responsive gallery.

Instalação

  1. Upload the sdaweb-social-galleri-feed folder to /wp-content/plugins/
  2. Activate the plugin through the Plugins menu
  3. Go to Social Galleri > Accounts tab
  4. Click Add Account, enter a label and paste your Facebook Page Access Token
  5. The plugin tests the connection and caches your feed automatically
  6. Add [sdawsoga_gallery] to any page or post
  7. For multiple accounts, use [sdawsoga_gallery account="slug"]

For token setup instructions, see the built-in setup guide in the Global tab.

Perguntas frequentes

Can I connect multiple Instagram accounts?

Yes. Go to the Accounts tab and add up to 20 accounts, each with its own token. Use [sdawsoga_gallery account="slug"] to display a specific account. The Shortcode Builder lets you select accounts visually.

Why do likes and comments show 0?

The Instagram Graph API only returns engagement metrics for accounts owned by the token holder.

Can I use multiple feeds on the same page?

Yes. Use the feed_id attribute: [sdawsoga_gallery feed_id="homepage"]. Each feed operates independently. Combine with account for different accounts: [sdawsoga_gallery account="oslo" feed_id="sidebar"].

How do I change the language?

Go to Social Galleri > Translations and update any string.

Does it work with page builders?

Yes. The shortcode works in Elementor, WPBakery, Divi, and any builder that supports WordPress shortcodes. A Gutenberg block is also available.

How fast does the feed load?

Feed data is embedded in the page HTML when the cache is warm (nearly always, thanks to per-account WP-Cron background refresh), so it loads instantly with zero network requests.

What Facebook Graph API permissions do I need?

Four permissions: instagram_basic, pages_show_list, pages_read_engagement, and instagram_manage_insights. All four are required for the feed — the plugin reads your posts through the Graph API Business Discovery endpoint, which needs the insights scope (it is also used by Stories). Omitting instagram_manage_insights causes a “(#10) Application does not have permission for this action” error when the feed loads. The setup guide in the plugin admin lists all of these with step-by-step instructions for Graph API Explorer.

Can I extend the plugin from my theme or another plugin?

Yes. The plugin documents 25 WordPress filter and action hooks covering rendering, post filtering, API data, SEO schema, and lifecycle events; docs/hooks.md inside the plugin folder has the full reference with copy-paste examples and says which hooks fire on the default gallery (the gallery is built in the browser, so the per-post helpers in PHP fire only from a custom template). Examples include: rewriting Instagram CDN picture addresses through your own image proxy, overriding the gallery template from your theme, and busting your page cache when the feed refreshes. All hooks are stable within the 5.x major version.

Avaliações

Não há avaliações para este plugin.

Colaboradores e desenvolvedores

“SDAweb Social Galleri Feed” é um programa de código aberto. As seguintes pessoas contribuíram para este plugin.

Colaboradores

Registro de alterações

The most recent releases are listed here. The complete history is in changelog.txt in the plugin folder.

5.4.0

  • Changed: pages load much faster. A page with a gallery used to carry the complete cached feed of every account — all 300 posts with every picture address and every album slide, about 1 MB on a page that shows 50 posts. The page now carries only what its galleries can show, with one extra “Load more” batch so the first click is still instant; later clicks fetch the next posts from the plugin’s own REST route, and visitors who never click download nothing more. Accounts not used on the page are no longer written into it, and posts Instagram delivers without a picture never leave the server. A gallery with a hashtag, exclude or media-type filter still receives the whole feed, because it filters in the browser. On the test site the page went from 1.2 MB to well under half of that.
  • Changed: the REST route /wp-json/sdawsoga/v1/feed accepts offset and per_page to page through a feed; without them it answers with the whole feed as before.
  • Changed: the plugin’s per-address rate limit (10 requests per 5 minutes) now applies only to requests that actually go to Instagram. It used to count every call to the plugin’s REST route, cached answers included, so a visitor clicking Load more more than ten times in five minutes — or a classroom behind one shared address — was cut off with an error.
  • Changed (developers): the sdawsoga_cached_feed_data filter now also runs on the page itself, where nearly every gallery view gets its posts; before, it ran only on the REST and AJAX routes, so a filter written after docs/hooks.md had no visible effect. The schema.org JSON-LD is now printed by PHP whenever the feed is on the page, so the sdawsoga_schema_markup filter fires too (same shape, once per page). docs/hooks.md gains a “Which hooks fire” section: eleven of the documented hooks live in renderer helpers the default browser-built gallery never calls, and the reference now says so and shows how to get the same result with sdawsoga_cached_feed_data.
  • Added (developers): four new hooks. sdawsoga_feed_item filters one post at a time just before it leaves the server (page and REST route) — rewrite a picture address or caption, or return false to hide the post; sdawsoga_feed_refreshed fires after a fresh feed has been stored, the moment to purge a page cache; sdawsoga_feed_need changes what a gallery asks to have inlined; sdawsoga_frontend_config filters everything handed to the browser script. All documented in docs/hooks.md.
  • Fixed: the gallery block’s “Wide width”, “Full width” and HTML anchor settings had no effect on the page — the block declared them but its output never carried the alignment class or the id. They work now. In the editor the block used to show “Loading gallery…” for ever, because the script that builds the gallery never runs inside the editor; it now shows a card with the block’s settings instead, and the gallery appears on the published page as before.
  • Fixed: in a theme that styles every picture inside a full-width block (The7 sets them to the full viewport width), a gallery block set to Wide or Full width showed each tile as a zoomed-in sliver of its picture, and the lightbox’s profile picture became viewport-wide. The gallery’s own picture sizes now take precedence over such theme rules.
  • Fixed: the Stories viewer now behaves as a dialog for keyboard and screen-reader users. It is announced as “Instagram Stories”, focus moves to its Close button when it opens, Escape and the left/right arrow keys work wherever focus is, Tab stays inside the viewer, and closing it returns focus to the profile avatar. Before, the keys only worked after clicking inside the viewer, and Tab wandered through the gallery behind it. A story video that cannot load now moves on to the next story instead of stopping the viewer.
  • Changed: the browser is told to connect early to the picture servers the feed actually uses. Instagram hands out regional addresses (for example scontent-arn2-1.cdninstagram.com), so the fixed address the plugin named before was never the one the pictures loaded from.
  • Changed: the pictures in the first row of the gallery are no longer marked for lazy loading, so the browser fetches them at once instead of waiting until layout is done; pictures further down stay lazy.
  • Fixed: the gallery’s buttons (Load more, lightbox arrows and Close) are now type=“button”, so a gallery placed inside a form no longer submits it when they are clicked.
  • Changed: readme and admin texts brought up to date — the Third-Party Services section now explains that visitors’ browsers load the pictures from Instagram’s servers, and that the token is also sent when a visitor opens a gallery with an empty cache; the Stories description no longer says videos play with sound (they are muted); a stale pointer to a removed “Tools” section is fixed; one outdated entry in the translation template is corrected.
  • Fixed: the profile avatar in the gallery header lost its round frame. Since 5.1.0 a style rule meant to strip the browser’s button look also removed the avatar’s size, round shape and thin grey border, so the picture was shown bare and at its own size, and the Stories ring sat off-centre. The avatar is framed again, the per-size and per-screen sizes apply again, and the Instagram gradient shows only while there are active Stories, as described. The avatar button also gets its keyboard focus outline back.
  • Fixed: the “Posts label”, “Followers label” and “Profile picture” fields under Translations had no effect on the gallery header — it always said “posts” and “followers” in English, and the profile picture’s text alternative was always “Profile picture”. The header now uses the three fields, like the rest of the gallery already did. If you had filled them in, you will see the change right after the update.
  • Fixed: when the cached feed had expired and the scheduled refresh was late (after a run of failed refreshes, or on sites where WP-Cron is switched off without a server cron), the page kept showing the backup copy of at most 50 posts and nothing ever asked Instagram for fresh posts. A page view that has to use the backup copy now starts a background refresh, as the gallery’s own data requests already did.
  • Fixed: in the lightbox, the up and down arrow keys now move to the previous and next post, as the hint for screen-reader users has always said. Left and right still step through an album’s pictures.
  • Fixed: the lightbox announced itself to screen readers with the “Post counter” word from Translations (“Post”, “Innlegg”) instead of its name, “Post viewer”.
  • Fixed: “Add Account” saved the token before testing it and reported success whatever the test said, so a mistyped or expired token was added with a green message, and the feed was first fetched by the first visitor to the page. The token is now tested first — a failing token is not saved and the reason is shown — and the feed is fetched and cached at once, as the setup guide has always said. The same applies when you change an account’s token: a token that fails the test does not replace the working one. The message after adding or changing an account now names the Instagram account and the number of posts fetched, or says why the feed could not be fetched (for example a token without the instagram_manage_insights permission).
  • Fixed: changing “Cache Duration” or “Max posts to sync” in Global settings had no effect until the next scheduled refresh, hours later, on every site that has accounts in the Accounts tab — the save cleared only the cache of the old single-account layout. Each account’s cache is now cleared and refreshed in the background right after saving; visitors keep seeing the backup copy in the meantime.
  • Fixed: the Instagram account details the plugin remembers next to a token (account ID and username) were handled the wrong way round when something went wrong. A network timeout threw them away (costing extra Instagram requests on the next refresh), while an Instagram error about the username — for example after the Instagram handle was renamed — kept them forever, so every refresh failed until an administrator clicked Test. Some older releases could also store the details with the username missing, which had the same effect. The plugin now keeps the details on a timeout, re-checks and retries once when Instagram rejects the username, and never stores details without a username. No action needed; this repairs itself on the next refresh.
  • Fixed: a field left empty under Translations (or the Follow / Load more button text under Appearance) showed nothing at all — an emptied month name made the lightbox date read “15. “, an emptied button text left an icon-only button — although the tab says “Leave empty to use defaults”. An empty field now shows the default. The default is now also translated: the English text that activation writes into every field no longer counts as your own text, so on a site in another language the plugin’s own translation of these strings shows as soon as one is installed. Text you typed yourself is used exactly as before.
  • Fixed: on screens 1024 px wide or narrower (tablets, phones, a small desktop window) the Tab key could leave the open lightbox and land on the page behind it, because the keyboard trap counted controls that are hidden at those sizes. Tab and Shift+Tab now stay inside the lightbox at every size.
  • Fixed: the hashtag filters matched the start of longer hashtags — hashtag=”jul” also showed posts tagged #juli and #julegave, and exclude_hashtags=”ad” also hid #advent. A tag now has to match the whole hashtag. If you relied on the old partial matching, add the longer tags explicitly.
  • Fixed: the settings page meant to warn before you leave with unsaved changes, but the warning never appeared in current browsers. It now does. It is only armed by the settings fields themselves, not by typing in the account manager or the Shortcode Builder, which are not saved with the form.

5.3.14

  • Fixed: on sites with a page cache (LiteSpeed Cache, WP Super Cache, Cloudflare …) the gallery could stop loading for all logged-out visitors until the cache was purged. It happened when a page was cached while the Instagram posts were not yet built into it — right after adding an account, or while Instagram was unreachable: the security codes in the cached page expire after 12–24 hours, and WordPress then refused the gallery’s own request. Logged-out visitors no longer send such a code — the feed is public, read-only data — so an old cached page keeps working. Nothing changes for logged-in users.
  • Fixed: after an image failed to load, “Load more” showed one post twice.
  • Fixed: a post that Instagram delivers without a picture address (it does that for some flagged or copyrighted content) made the browser request a non-existent page on your site on every page view, and showed as a broken image in the lightbox. Such posts, and such slides inside an album, are now left out.
  • Fixed: when the gallery could not be loaded, the error message was written and then hidden again at once, so visitors and administrators saw an empty area. The message — the “error” text under Translations — is now shown, and announced to screen readers.
  • The complete version history has moved to changelog.txt in the plugin folder; this section lists the most recent releases.

5.3.13

  • Security hardening: two old copies of the Instagram access token are now removed. (1) Sites that upgraded from 4.x to 5.0 kept the original single-account token after it was copied to the new account; if an administrator later deleted every account, the plugin quietly started using that old token again. It is now deleted once the accounts have their own token, and when all accounts have been removed. (2) Sites that once ran a release older than 4.6 still had that release’s token stored unencrypted under its old option name. It is now deleted.
  • Fixed: deleting the plugin never removed the options of releases older than 4.6 (including that unencrypted token), because the clean-up checked a flag it had just deleted. They are now removed — but only when they are recognisably this plugin’s own, so another plugin’s settings that happen to share the short old prefix are never touched.
  • Deleting the plugin now also removes the short-lived markers introduced in 5.3.12.
  • No visible changes and no settings to review.

5.3.12

  • Fix: limit=”X” on the shortcode (and “Posts to show” in the block) had no effect — the per-device post counts from the settings always won. An explicit limit now sets a fixed count on every screen size, as the settings page always described. If your shortcode contains a limit, the gallery will show that number of posts after this update.
  • Fix: columns=”X” on the shortcode (and “Columns” in the block) had no effect. An explicit value now sets the column count on desktop and laptop screens and caps the smaller breakpoints, so a gallery never shows more columns on a tablet than on a desktop. If your shortcode contains columns, the layout will follow it after this update.
  • Changed: in the block, “Posts to show” and “Columns” now default to 0 = “use the per-device values from the plugin settings”. Existing blocks that were left at the old defaults (9 / 3) keep looking exactly as they do today.
  • Fix: every apostrophe in a lightbox caption was corrupted — “It’s” appeared as “It&”, a link “#39” and “;s”.
  • Fix: hashtags and mentions with non-English letters were cut at the first such letter — “#søndag” became a link “#s” followed by plain “øndag”. Hashtags and mentions are now fully Unicode-aware, email addresses are no longer turned into mentions, and links are URL-encoded.
  • Fix: when an account’s fetch kept failing (for example a token without the instagram_manage_insights permission), every page view by every visitor ran the full Instagram request sequence again — twice. A failed fetch is now remembered for five minutes; scheduled refreshes, “Refresh now” and “Clear cache” are unaffected.
  • Fix: an unexpected response from Instagram without feed data was stored as an empty gallery and written over the backup copy. It is now treated as a failure, and an empty result never replaces a backup that contains posts.