Description
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 with sound
* 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 — Server-side inline JSON per account, 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
* Smart fetch limit — Only requests what’s needed from the API
* Lazy loading and incremental grid rendering
* Per-IP rate limiting
Localization
* All 30+ frontend strings configurable in admin (Norwegian defaults)
* 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 — textContent used instead of innerHTML, 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 targetinglimit— Number of posts to display (default: 9)columns— Number of columns (default: 3)layout— grid, masonry, or highlightaspect_ratio— square, portrait, instagram, or originalpadding— Gap between images in pixelsshow_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 carouselhashtag— Only show posts containing this hashtagexclude_hashtags— Comma-separated hashtags to excludeshow_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
instagram_basicpermission - 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.
- Service: Instagram Graph API / Facebook Graph API
- Website: https://developers.facebook.com/
- Terms of Use: https://developers.facebook.com/terms/
- Privacy Policy: https://www.facebook.com/privacy/policy/
When data is sent: When the plugin refreshes the feed cache (via WP-Cron background refresh or manual cache clear in the admin panel). 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 data is collected or transmitted. The plugin does not track site visitors or send any visitor information to external services.
Screenshots
Blocks
This plugin provides 1 block.
- Social Galleri Feed Display your Instagram feed as a responsive gallery.
Installation
- Upload the
sdaweb-social-galleri-feedfolder to/wp-content/plugins/ - Activate the plugin through the Plugins menu
- Go to Social Galleri > Accounts tab
- Click Add Account, enter a label and paste your Facebook Page Access Token
- The plugin tests the connection and caches your feed automatically
- Add
[sdawsoga_gallery]to any page or post - For multiple accounts, use
[sdawsoga_gallery account="slug"]
For token setup instructions, see the built-in setup guide in the Global tab.
FAQ
-
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_idattribute:[sdawsoga_gallery feed_id="homepage"]. Each feed operates independently. Combine withaccountfor 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?
-
For the basic feed:
instagram_basic,pages_show_list, andpages_read_engagement. If you also enable Stories, addinstagram_manage_insights— Stories use a separate Instagram Graph API endpoint that requires the insights scope. 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 exposes 21 documented WordPress filter and action hooks covering rendering, post filtering, API data, SEO schema, and lifecycle events. Full documentation with copy-paste examples lives in
docs/hooks.mdinside the plugin folder. Examples include: rewriting Instagram CDN thumbnails through your own image proxy, overriding the gallery template from your theme, post-processing captions to embed YouTube links, and busting your page cache when the feed refreshes. All hooks are stable within the 5.x major version.
Reviews
There are no reviews for this plugin.
Contributors & Developers
“SDAweb Social Galleri Feed” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “SDAweb Social Galleri Feed” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
5.3.1
- Fix: Undefined variable
$month_labelsin admin settings “Month Names” section. The month label header now correctly reads from$month_defaults. On PHP 8+ this previously emitted PHP warnings; functionally the field labels were empty. - Compatibility: Verified compatibility with PHP 8.5.
5.3.0
- Developers: Formally documented 21 existing WordPress filter and action hooks as a stable public API. See docs/hooks.md inside the plugin folder for full reference with copy-paste examples. Hooks cover rendering (sdawsoga_shortcode_attributes, sdawsoga_gallery_template_path, sdawsoga_gallery_output, sdawsoga_thumbnail_url, sdawsoga_permalink, sdawsoga_formatted_timestamp, sdawsoga_caption_before_process, sdawsoga_caption_after_process, sdawsoga_is_carousel, sdawsoga_media_type_label, sdawsoga_error_message_html), post filtering (sdawsoga_filtered_posts, sdawsoga_hashtag_filtered_posts, sdawsoga_exclude_hashtags_filtered_posts), API and cached data (sdawsoga_cached_feed_data, sdawsoga_fresh_feed_data, sdawsoga_after_api_fetch, sdawsoga_stories_data), SEO schema (sdawsoga_schema_markup), and lifecycle events (sdawsoga_before_api_fetch, sdawsoga_cache_cleared).
- Developers: All documented hooks are now stable within the 5.x major version — they will not be removed or renamed without going through the standard _deprecated_hook() cycle.
- Documentation: New FAQ entry “Can I extend the plugin from my theme or another plugin?” pointing developers at the hooks documentation.
- No user-visible changes — if you don’t write code against the new public hooks API, the plugin behaves identically to 5.2.4.
5.2.4
- Performance: Gallery item images now have explicit width and height attributes parsed from the Instagram CDN URL pattern (/p640x640/, /s320x320/, etc.). Eliminates Cumulative Layout Shift on masonry and original-aspect-ratio layouts.
- Reliability: Pagination cursor sanitization no longer strips period characters. Meta has historically used several base64 variants in pagination cursors; the previous regex was overly aggressive and could silently break pagination if Meta returned a cursor containing a “.”
- Hygiene: When the Stories feature is toggled off, the plugin now immediately clears any pending Stories cron events for all accounts. Previously they kept consuming Graph API quota until each one fired and saw that stories were disabled.
- i18n: The “Loading gallery…” text in the initial template now respects the admin-customizable label from Components > Translations, matching how the rest of the frontend strings work.
- Documentation: Admin setup guide and readme FAQ now document the additional
instagram_manage_insightspermission required if you enable Stories.
5.2.3
- Accessibility: Lightbox modal now declares dialog semantics statically (role=”dialog”, aria-modal, aria-label, aria-describedby) so accessibility audits and screen-reader navigation see them on initial render, not only after open
- Accessibility: Added a screen-reader hint inside the lightbox describing the keyboard shortcuts (Escape, arrow keys, swipe-up to close)
- Accessibility: Broadened prefers-reduced-motion coverage from a few elements to a blanket plugin-scoped pattern using the 0.01ms idiom (preserves animationend events for any code waiting on them)
- Accessibility: Expanded :focus-visible outline coverage to include post navigation arrows, dot indicators, and Story viewer controls
- i18n: The block editor script now loads its translations via wp_set_script_translations() so the inserter labels and inspector controls can be localized
- Privacy: Privacy policy content now also discloses that profile pictures, post images, and video thumbnails are loaded directly from Instagram’s CDN (scontent.cdninstagram.com), exposing visitor IPs to Meta on every page render
- Improved: SDAWSOGA_VERSION constant now reads dynamically from the plugin header via get_file_data() — single source of truth, eliminates version drift
- Improved: Build script now auto-syncs block.json and block-editor.asset.php version metadata from the plugin header at build time
- Fixed: block-editor.asset.php fallback version updated from a stale 4.10.1 to current
- Cleanup: Plugin header author corrected — “Rune Stake Stavdal” (the original spelling, restored after a previous propagated error in a sibling plugin’s checklist template)
5.2.2
- Improved: Full internationalization audit — all 36 frontend label defaults now wrapped in translation functions
- Improved: All admin form labels and placeholders in the Translations tab are now properly translatable
- Improved: Replaced hardcoded Norwegian placeholder text with translatable English defaults
- Improved: Created complete POT file (597 entries) — was previously missing entirely
- Improved: Added block.json title and description to POT for block editor translation
- Fixed: Added translator comments for all strings containing %d placeholders
5.2.1
- Fixed: Gallery images no longer flicker or fade-in again when scrolling up and down.
- Performance: Removed content-visibility that caused re-paint flicker on scroll.
- Performance: GPU compositing layers (will-change) now only activate on hover instead of permanently.
- Performance: Removed duplicate hover transform on images to reduce compositing work.
- Changed: Removed grey placeholder background from grid items for a cleaner loading appearance.
5.2.0
- Added: Permanent Page Token support — tokens that never expire now work alongside 60-day User Tokens.
- Added: Setup guide updated with step-by-step instructions for obtaining a non-expiring token.
- Added: Copy-to-clipboard toast notification replaces inline button text swap in Shortcode Builder.
- Changed: All default strings now in English (base language). Existing sites with saved translations are unaffected.
- Changed: Images load with a fast 200ms opacity fade from placeholder background instead of slow staggered animation.
- Fixed: Account deletion now correctly detects and reassigns the default account.
- Fixed: Avatar renders as a plain element (not a button) when Stories are disabled.
- Fixed: Custom bio HTML no longer rendered as plain text on the frontend.
- Fixed: Double clipboard toast no longer fires when copying shortcodes.
- Fixed: Enter key in account fields triggers Add Account instead of submitting the settings form.
- Fixed: Keyboard listeners cleaned up when gallery is removed from DOM during open modal.
- Fixed: Double-escaped gallery ID in template output.
- Fixed: Uninstall now removes all plugin options including Stories and filter settings.
- Fixed: CSS aspect-ratio fallback added for Safari 14 and older.
- Improved: Block editor script now runs in strict mode.
- Improved: Render method docblocks document escaped HTML return contract.
5.1.1
- Fixed: Images no longer flicker or show blank placeholders when scrolling back to the feed on mobile.
5.1.0
- Added: Instagram Stories integration — active Stories display as a gradient ring around the profile avatar.
- Added: Fullscreen Story viewer with progress bars, auto-advance (5s for images, video duration for videos), tap-to-navigate, and keyboard support.
- Added: Per-account Stories cron refresh every 15 minutes (only when Stories feature is enabled).
- Added: “Show Stories” toggle in Behavior tab (default: off).
- Added:
show_storiesshortcode attribute for per-feed control. - Added: Stories data injected inline per account for zero-AJAX display.
- Added: Video Stories play automatically with sound in the viewer.
- Note: Stories expire after 24 hours (Instagram API limitation). Only available for accounts you own a token for.
5.0.0
- Added: Multi-account support — connect up to 20 Instagram accounts with individual tokens, caches, and cron schedules.
- Added: Accounts admin tab — add, edit, delete, test connection, and clear cache per account.
- Added:
accountshortcode attribute and Gutenberg block attribute for selecting which account to display. - Added: Per-account cache keys, stale backups, and failure counters — accounts don’t interfere with each other.
- Added: REST API
?account=parameter with sanitize_key validation. - Added: Shortcode Builder redesigned with prominent account selector header showing username and post count.
- Added: Auto-migration from single-account to multi-account storage on upgrade.
- Changed: Admin restructured from 9 tabs to 7 — Header, Buttons, and Lightbox merged into Appearance; API renamed to Global (token management moved to Accounts); Advanced renamed to Behavior.
- Changed: Gallery Name (formerly Feed ID) now has clearer labeling and description.
- Changed: Plugin overview, setup guide, and help documentation updated for multi-account workflow.
- Improved: Per-account WP-Cron scheduling with proper args-based event management.
- Improved: Uninstall cleanup handles all per-account options, transients, and cron events.
4.12.0
- Improved: Lightbox backdrop changed to solid black for full immersion.
- Improved: Grid item hover effect upgraded — snappier scale (1.03), GPU-accelerated with will-change.
- Improved: Hover overlay now slides up with cubic-bezier easing for a premium feel.
- Improved: Grid images fade in smoothly on load instead of popping in.
- Improved: Close button hover uses scale instead of rotate for a modern look.
- Improved: All modal close paths (button, backdrop click, Escape, swipe) now animate consistently.
- Improved: Swipe detection uses velocity + lower threshold (35px) for more responsive touch navigation.
- Improved: Swipe-up-to-close also uses velocity detection for natural feel.
- Improved: Swipe hint shows for 1.5s (was 3s) and repositioned above mobile nav buttons.
- Improved: Focus rings use :focus-visible with Instagram blue (#0095f6) for better keyboard accessibility.
- Improved: Next/previous post images preloaded in lightbox for instant navigation.
4.11.0
- Added: Exponential backoff on API failures — retry interval doubles per consecutive failure (capped at 24h), resuming normal schedule on success.
- Fix: Consecutive failure counter resets when admin changes the API token, so backoff doesn’t carry over to a new token.
4.10.5
- Fix: Consistent cron cleanup — uninstall.php and clear_all() now use wp_clear_scheduled_hook() matching deactivation behavior.
4.10.4
- Fix: Hashtag filtering now uses word-boundary matching — #pizza no longer matches #pizzanight.
- Fix: Instagram API pagination cursor no longer corrupted by over-aggressive sanitization on large feeds.
- Fix: Template path filter validated against plugin/theme directories to prevent arbitrary file inclusion.
- Fix: IP rate limiting uses salted hash (wp_hash) instead of plain MD5.
- Fix: Token encryption uses random_bytes() instead of deprecated openssl_random_pseudo_bytes().
- Fix: Schema.org JSON-LD data sanitized with esc_url_raw() and sanitize_user().
- Fix: Token mask check uses strict pattern to prevent edge-case save bypass.
- Fix: Plugin deactivation uses wp_clear_scheduled_hook() for reliable cron cleanup.
- Fix: Token decryption failures now logged when WP_DEBUG is enabled; base64 decode uses strict mode.
- Accessibility: Admin settings tabs have proper ARIA roles (tablist, tab, tabpanel).
- Accessibility: Gallery grid container has aria-live=”polite” for screen reader announcements on load-more.
- Code quality: Duplicate hex color regex extracted to constants in admin script.
- Code quality: Feed ID attribute capped at 50 characters.
4.10.3
- Fix: SVG icons in lightbox (swipe hint, close button, nav arrows, media type badge) could render at wrong size due to CSS specificity conflict with the modal SVG reset. All SVG rules now use scoped selectors to prevent theme or reset overrides.
4.10.2
- Fix: Removed legacy unprefixed tg_gallery shortcode alias for WordPress.org compliance.
- Improved: Block editor UI strings internationalized with wp.i18n for translation support.
- Added: Tested up to header in main plugin file.
4.10.1
- Fix: Re-tagged release to ensure update delivery to all users.
4.10.0
- Performance: Grid items use DocumentFragment for batched DOM appends (single reflow instead of per-item).
- Performance: Hover overlay DOM created lazily on first mouseenter instead of at render time (~12 fewer nodes per item).
- Performance: CSS content-visibility: auto on grid and highlight layout items skips rendering for off-screen posts.
- Performance: Images use decoding=”async” for off-thread decode in grid and lightbox.
4.9.0
- Added: Gutenberg block — insert the gallery from the block editor with visual settings in the sidebar.
- Added: sdawsoga_max_sync_posts to default options registry (was missing from activation and migration).
- Improved: Stale feed backup now truncated to 50 posts to prevent wp_options table bloat.
- Improved: REST API fetch includes X-WP-Nonce header for authenticated request context.
- Improved: Resize event listener cleanup via MutationObserver prevents memory leaks in SPA environments.
- Fixed: Legacy tg_ prefix options are now cleaned up on plugin uninstall.
4.8.0
- Post navigation arrows in lightbox backdrop — jump between posts on desktop, hidden on mobile where bottom nav bar handles it.
- Shortcode Builder admin tab — visually configure feeds and copy generated shortcodes with live preview.
- Clickable hashtags and @mentions in lightbox captions — matches PHP-rendered hover overlay.
- Enable/disable lightbox setting now wired to frontend — when disabled, grid images link directly to Instagram.
- Schema.org JSON-LD markup injected when feed loads (SocialMediaPosting with author data).
- Admin quick-links (Overview, Setup Guide) now switch to API tab first when clicked from other tabs.
- Updated Overview panel with post navigation docs and expanded shortcode reference table.
- Renamed legacy _tg references, removed duplicate variable declarations, cleaned up file header versions.
4.7.8
- Clear Cache now immediately re-fetches feed data — works reliably when WP-Cron is disabled (DISABLE_WP_CRON).
- Reduced API page size from 100 to 33 posts per request — prevents “reduce data” errors on accounts with carousel/children data.
- Clear Cache shows actual API error message on failure instead of generic text.
- Improved “Posts to show” description — clarifies Load More batch behavior and sync relationship.
4.7.5
- Responsive “Posts to show” — 6-breakpoint system matching responsive columns (desktop, laptop, tablet landscape, tablet portrait, mobile landscape, mobile portrait).
- Debounced resize handler recalculates visible posts on viewport change, preserving Load More state.
- Access token masked in admin HTML source (credential security hardening).
- Unsaved changes warning (beforeunload) in admin settings.
- Fixed stale [TG Admin] prefix in debug log.
- Replaced trademark dashicon (dashicons-instagram) with generic icon.
- Corrected author header format to match WordPress.org standard.
4.7.3
- Max posts to sync increased from 50 to 300 with automatic API pagination.
- Improved admin description for sync setting.
4.7.2
- Admin UI redesign: quick-access pill bar, tabbed Plugin Overview card (Layouts, Lightbox, Content, Performance, Security, Shortcodes), collapsible info cards, info tooltips on technical terms, shortcode reference table with parameter docs
- Fixed unprefixed variables in uninstall.php
- Added missing contributor to readme.txt
4.7.1
- Removed Plugin URI header to comply with WordPress.org guidelines (was identical to Author URI)
4.7.0
- Added: Video badge on grid items — shows a “Video” badge on VIDEO posts (toggle in Advanced > Carousel & Video)
- Added: Keyboard support for carousel dots — dots are focusable with Tab, activatable with Enter/Space
- Added: Default hashtag and exclude filters — set global defaults in Layout tab, shortcode attributes override
- Added: Cache refresh failure counter — red inline count shown in API tab cache status when consecutive failures > 0
4.6.0
- Added: Content moderation — blacklist words filter hides posts with blocked words/phrases
- Added: Video autoplay on hover — muted video preview plays when hovering over video posts in the grid
- Added: Carousel autoplay in lightbox — auto-advance slides with configurable interval and progress bar
- Added: Persistent API failure notice — warning shown on settings page when feed refresh fails 3+ times consecutively
4.5.4
- Fixed missing JS, template, and include files that were absent from the 4.5.3 SVN tag
- Whitespace and trailing-space cleanup across CSS, PHP, and JS files
4.5.3
- Renamed all frontend CSS classes and variables from generic tg- prefix to unique sdawsoga- prefix for better namespace compliance
4.5.2
- Fixed fatal error: wp_salt() called before pluggable.php is loaded
- Deferred cron scheduling to init hook for compatibility with all hosting environments
4.5.1
- Removed custom CSS editor per WordPress.org guidelines
- Fixed inline CSS escaping with wp_strip_all_tags()
- Fixed main plugin filename to match plugin slug
- Fixed settings link URL on Plugins page
4.5.0
- Security: Constant definition guards, CSS sanitizer hardened, IP validation, error code sanitization
- Fixed: XSS — lightbox and caption rendering switched to DOM element creation
- Added: 6-breakpoint responsive column cascade via CSS variables
- Improved: Conditional asset loading, smart cache clearing
4.4.0
- Max posts to sync setting, translatable post counter, improved cache status and mobile follow button
4.3.1
- WordPress.org trademark compliance: renamed plugin, added directory protection and license
4.3.0
- Inline JSON feed loading, REST API endpoint, stale-while-revalidate caching, WP-Cron background refresh
4.2.0
- Lightbox engagement stats, translations tab, swipe-up-to-close, security hardening (Bearer auth, CSRF, XSS)
4.1.0
- Initial release with grid/masonry/highlight layouts, lightbox, profile header, responsive columns





