{"id":282597,"date":"2026-02-18T20:09:58","date_gmt":"2026-02-18T20:09:58","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/sdaweb-social-galleri-feed\/"},"modified":"2026-10-30T22:14:42","modified_gmt":"2026-10-30T22:14:42","slug":"sdaweb-social-galleri-feed","status":"publish","type":"plugin","link":"https:\/\/es-ar.wordpress.org\/plugins\/sdaweb-social-galleri-feed\/","author":23453481,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"6.0.1","stable_tag":"6.0.1","tested":"7.1.4","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"SDAweb Social Galleri Feed","header_author":"SDAweb - Rune Stake Stavdal, Vinjar Romsvik, Christer Andvik","header_description":"Display your Instagram feed as a responsive gallery with lightbox, instant loading, and full admin control.","assets_banners_color":"fafafc","last_updated":"2026-10-30 22:14:42","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/sdaweb.no","rating":0,"author_block_rating":0,"active_installs":30,"downloads":3127,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"4.10.0":{"tag":"4.10.0","author":"rstake","date":"2026-03-15 19:20:57","revision":3483262},"4.10.1":{"tag":"4.10.1","author":"rstake","date":"2026-03-15 21:27:10","revision":3483313},"4.10.2":{"tag":"4.10.2","author":"rstake","date":"2026-03-19 19:29:37","revision":3486791},"4.10.3":{"tag":"4.10.3","author":"rstake","date":"2026-04-01 12:00:22","revision":3496510},"4.10.4":{"tag":"4.10.4","author":"rstake","date":"2026-04-01 12:23:44","revision":3496531},"4.10.5":{"tag":"4.10.5","author":"rstake","date":"2026-04-01 12:51:00","revision":3496565},"4.11.0":{"tag":"4.11.0","author":"rstake","date":"2026-04-01 13:01:01","revision":3496590},"4.12.0":{"tag":"4.12.0","author":"rstake","date":"2026-04-01 13:19:52","revision":3496622},"4.5.1":{"tag":"4.5.1","author":"rstake","date":"2026-02-18 21:50:54","revision":3464647},"4.5.2":{"tag":"4.5.2","author":"rstake","date":"2026-02-25 00:16:31","revision":3468974},"4.5.4":{"tag":"4.5.4","author":"rstake","date":"2026-02-25 08:31:53","revision":3469184},"4.7.0":{"tag":"4.7.0","author":"rstake","date":"2026-02-25 22:42:38","revision":3469759},"4.7.1":{"tag":"4.7.1","author":"rstake","date":"2026-03-01 21:38:57","revision":3472261},"4.7.2":{"tag":"4.7.2","author":"rstake","date":"2026-03-08 14:11:58","revision":3477441},"4.7.3":{"tag":"4.7.3","author":"rstake","date":"2026-03-09 22:45:53","revision":3478588},"4.7.8":{"tag":"4.7.8","author":"rstake","date":"2026-03-10 00:03:41","revision":3478631},"4.8.0":{"tag":"4.8.0","author":"rstake","date":"2026-03-13 23:55:53","revision":3482322},"5.1.0":{"tag":"5.1.0","author":"rstake","date":"2026-04-01 19:48:21","revision":3496960},"5.1.1":{"tag":"5.1.1","author":"rstake","date":"2026-04-01 21:31:23","revision":3497044},"5.2.0":{"tag":"5.2.0","author":"rstake","date":"2026-04-03 09:50:14","revision":3498099},"5.2.1":{"tag":"5.2.1","author":"rstake","date":"2026-04-03 12:35:22","revision":3498234},"5.2.2":{"tag":"5.2.2","author":"rstake","date":"2026-04-04 21:41:16","revision":3498927},"5.2.3":{"tag":"5.2.3","author":"rstake","date":"2026-04-11 21:41:31","revision":3504184},"5.2.4":{"tag":"5.2.4","author":"rstake","date":"2026-04-11 22:58:33","revision":3504197},"5.3.0":{"tag":"5.3.0","author":"rstake","date":"2026-04-11 23:12:31","revision":3504202},"5.3.1":{"tag":"5.3.1","author":"rstake","date":"2026-04-24 11:54:22","revision":3514604},"5.3.10":{"tag":"5.3.10","author":"rstake","date":"2026-08-15 13:03:10","revision":3648617},"5.3.11":{"tag":"5.3.11","author":"rstake","date":"2026-08-31 14:43:42","revision":3674473},"5.3.12":{"tag":"5.3.12","author":"rstake","date":"2026-09-20 17:12:05","revision":3704494},"5.3.13":{"tag":"5.3.13","author":"rstake","date":"2026-09-20 20:14:32","revision":3704589},"5.3.14":{"tag":"5.3.14","author":"rstake","date":"2026-09-21 18:50:59","revision":3706166},"5.3.2":{"tag":"5.3.2","author":"rstake","date":"2026-05-10 19:53:01","revision":3527989},"5.3.4":{"tag":"5.3.4","author":"rstake","date":"2026-05-11 07:49:25","revision":3528364},"5.3.5":{"tag":"5.3.5","author":"rstake","date":"2026-05-12 20:56:55","revision":3530358},"5.3.6":{"tag":"5.3.6","author":"rstake","date":"2026-05-20 12:55:13","revision":3539311},"5.3.7":{"tag":"5.3.7","author":"rstake","date":"2026-06-16 13:01:48","revision":3574544},"5.3.8":{"tag":"5.3.8","author":"rstake","date":"2026-06-18 18:46:35","revision":3577706},"5.3.9":{"tag":"5.3.9","author":"rstake","date":"2026-06-18 19:35:42","revision":3577766},"5.4.0":{"tag":"5.4.0","author":"rstake","date":"2026-10-15 17:06:31","revision":3749002},"6.0.0":{"tag":"6.0.0","author":"rstake","date":"2026-10-30 21:56:17","revision":3776079},"6.0.1":{"tag":"6.0.1","author":"rstake","date":"2026-10-30 22:14:42","revision":3776098}},"upgrade_notice":{"6.0.1":"<p>Copied pictures are now stored as WebP where the server supports it, and album slides in two sizes: a smaller cache and smaller downloads at the same quality. Existing copies are kept; switch the setting off and on again to rebuild them as WebP.<\/p>","6.0.0":"<p>Pictures are now copied to your site in three sizes and served from there: far less data per page, no visitor connection to Meta for pictures. Copying runs in the background and needs about 200 MB per 300 posts; switch it off under Behavior if you prefer. Includes the 5.4.1 fixes.<\/p>","5.4.1":"<p>Fixes a crash anyone could trigger on the feed route, stops a failing feed from calling Instagram on every page view, and makes Load more work when REST is blocked or the account label has an underscore. Recommended for all users.<\/p>","5.4.0":"<p>Pages with a gallery load much faster: only the posts the page can show are built into it, Load more fetches the rest. Also fixes the header avatar frame, the Translations labels and several lightbox, token and cache issues. Hashtag filters now match whole hashtags only \u2014 see the changelog.<\/p>","5.3.14":"<p>Fixes a gallery that stops loading for visitors on page-cached sites, a duplicated post after &quot;Load more&quot;, requests for a non-existent page caused by posts without a picture, and the error message that was never visible.<\/p>","5.3.13":"<p>Security hardening: removes old, no longer used copies of the Instagram access token left behind by earlier upgrades, and makes uninstall clean up completely. No visible changes.<\/p>","5.3.12":"<p>Shortcode limit and columns now work, captions with apostrophes and hashtags like #s\u00f8ndag display correctly, and a failing Instagram connection no longer slows down every page view. If your shortcode sets limit or columns, the gallery will now follow them.<\/p>","5.2.0":"<p>Permanent token support (no more 60-day expiry), English defaults, bug fixes, and improved image loading. Recommended for all users.<\/p>","5.1.1":"<p>Fix: images no longer flicker when scrolling back to the feed on mobile.<\/p>","5.1.0":"<p>Instagram Stories integration: active Stories show as a gradient ring on the profile avatar. Click to view in a fullscreen viewer with auto-advance and tap navigation. Enable in Behavior tab.<\/p>","5.0.0":"<p>Major release: Multi-account support (up to 20 accounts), redesigned admin (9 tabs consolidated to 7), visual Shortcode Builder with account selector. Existing single-account setups auto-migrate \u2014 no action needed.<\/p>","4.6.0":"<p>New features: content moderation, video hover preview, carousel autoplay, and API failure alerts. All are opt-in via the Behavior tab.<\/p>","4.5.4":"<p>Fixes missing files from the 4.5.3 SVN release. Recommended for all users.<\/p>","4.5.3":"<p>Frontend CSS prefix renamed from tg- to sdawsoga- for namespace compliance. No settings changes needed.<\/p>","4.5.2":"<p>Fixes fatal error on sites where wp_salt() is unavailable during plugin loading. Recommended for all users.<\/p>","4.5.1":"<p>WordPress.org compliance: removed custom CSS editor, fixed escaping, corrected plugin filename.<\/p>","4.5.0":"<p>Security hardening and responsive column fixes. Recommended for all users.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3471763,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3471763,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3471763,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3471763,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":{"sdawsoga\/gallery":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"sdawsoga\/gallery","version":"6.0.1","title":"Social Galleri Feed","category":"embed","icon":"format-gallery","description":"Display your Instagram feed as a responsive gallery.","keywords":["instagram","gallery","feed","social"],"textdomain":"sdaweb-social-galleri-feed","supports":{"html":false,"align":["wide","full"],"anchor":true},"attributes":{"feedId":{"type":"string","default":""},"account":{"type":"string","default":""},"limit":{"type":"number","default":0},"columns":{"type":"number","default":0},"layout":{"type":"string","default":"","enum":["","grid","masonry","highlight"]},"aspectRatio":{"type":"string","default":"","enum":["","square","instagram","portrait","original"]},"showHeader":{"type":"boolean","default":true},"showLoadmore":{"type":"boolean","default":true},"hashtag":{"type":"string","default":""},"excludeHashtags":{"type":"string","default":""}},"editorScript":"file:..\/..\/assets\/js\/block-editor.js"}},"tagged_versions":["4.10.0","4.10.1","4.10.2","4.10.3","4.10.4","4.10.5","4.11.0","4.12.0","4.5.1","4.5.2","4.5.4","4.7.0","4.7.1","4.7.2","4.7.3","4.7.8","4.8.0","5.1.0","5.1.1","5.2.0","5.2.1","5.2.2","5.2.3","5.2.4","5.3.0","5.3.1","5.3.10","5.3.11","5.3.12","5.3.13","5.3.14","5.3.2","5.3.4","5.3.5","5.3.6","5.3.7","5.3.8","5.3.9","5.4.0","6.0.0","6.0.1"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3471763,"resolution":"1","location":"assets","locale":"","width":1200,"height":900},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3471763,"resolution":"2","location":"assets","locale":"","width":1200,"height":900},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3465870,"resolution":"3","location":"assets","locale":"","width":1200,"height":900},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3471763,"resolution":"4","location":"assets","locale":"","width":1200,"height":900},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3471763,"resolution":"5","location":"assets","locale":"","width":1200,"height":900}},"screenshots":{"1":"Grid gallery on frontend","2":"Lightbox with engagement stats","3":"Admin settings \u2014 Accounts tab with multi-account management","4":"Admin settings \u2014 Shortcode Builder with account selector","5":"Mobile lightbox view"}},"plugin_section":[],"plugin_tags":[252,210,311,237,154],"plugin_category":[50,56],"plugin_contributors":[257114,256141],"plugin_business_model":[],"class_list":["post-282597","plugin","type-plugin","status-publish","hentry","plugin_tags-feed","plugin_tags-gallery","plugin_tags-instagram","plugin_tags-lightbox","plugin_tags-social-media","plugin_category-media","plugin_category-social-and-sharing","plugin_contributors-rstake","plugin_contributors-sdaweb","plugin_committers-rstake"],"banners":{"banner":"https:\/\/ps.w.org\/sdaweb-social-galleri-feed\/assets\/banner-772x250.png?rev=3471763","banner_2x":"https:\/\/ps.w.org\/sdaweb-social-galleri-feed\/assets\/banner-1544x500.png?rev=3471763","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/sdaweb-social-galleri-feed\/assets\/icon-128x128.png?rev=3471763","icon_2x":"https:\/\/ps.w.org\/sdaweb-social-galleri-feed\/assets\/icon-256x256.png?rev=3471763","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/sdaweb-social-galleri-feed\/assets\/screenshot-1.png?rev=3471763","caption":"Grid gallery on frontend"},{"src":"https:\/\/ps.w.org\/sdaweb-social-galleri-feed\/assets\/screenshot-2.png?rev=3471763","caption":"Lightbox with engagement stats"},{"src":"https:\/\/ps.w.org\/sdaweb-social-galleri-feed\/assets\/screenshot-3.png?rev=3465870","caption":"Admin settings \u2014 Accounts tab with multi-account management"},{"src":"https:\/\/ps.w.org\/sdaweb-social-galleri-feed\/assets\/screenshot-4.png?rev=3471763","caption":"Admin settings \u2014 Shortcode Builder with account selector"},{"src":"https:\/\/ps.w.org\/sdaweb-social-galleri-feed\/assets\/screenshot-5.png?rev=3471763","caption":"Mobile lightbox view"}],"raw_content":"<!--section=description-->\n<p>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 \u2014 connect up to 20 accounts and display different feeds on different pages. Built for speed \u2014 feeds load instantly on cached pages with zero network requests.<\/p>\n\n<h4>Features<\/h4>\n\n<p><strong>Multi-Account Support<\/strong>\n* Connect up to 20 Instagram accounts, each with its own token and cache\n* Per-account test connection, cache management, and failure tracking\n* Display different accounts on different pages with the <code>account<\/code> shortcode attribute\n* Visual Shortcode Builder shows which account you're building for<\/p>\n\n<p><strong>Layout &amp; Design<\/strong>\n* Multiple layouts \u2014 Grid, masonry, and highlight modes\n* Responsive columns \u2014 Separate settings for desktop, laptop, tablet, and mobile\n* Profile header \u2014 Avatar, username, follower count, bio, and follow button\n* Hover effects \u2014 Overlay on image hover with gradient\n* Color pickers \u2014 Customize likes icon, comments icon, and date text colors<\/p>\n\n<p><strong>Instagram Stories<\/strong>\n* Story ring \u2014 Gradient ring on avatar when Stories are active (like Instagram)\n* Fullscreen Story viewer \u2014 Auto-advance, tap navigation, progress bars, keyboard support\n* Video Stories play automatically (muted by default)\n* Per-account Stories refresh every 15 minutes via WP-Cron\n* Toggle on\/off globally or per shortcode<\/p>\n\n<p><strong>Lightbox<\/strong>\n* Fullscreen lightbox \u2014 Carousel navigation with keyboard and swipe support\n* Swipe-up-to-close \u2014 Mobile-native gesture\n* Engagement stats \u2014 Likes, comments, media type badge, and relative date<\/p>\n\n<p><strong>Content &amp; Filtering<\/strong>\n* Multiple feeds \u2014 Use <code>feed_id<\/code> attribute for independent feeds on different pages\n* Hashtag filtering \u2014 Include or exclude posts by hashtag\n* Media type filter \u2014 Filter by image, video, or carousel\n* Load more \u2014 Paginated loading with customizable button<\/p>\n\n<p><strong>Performance<\/strong>\n* Instant loading \u2014 The first screens are built into the page, zero network requests on cache hit\n* REST API endpoint with legacy AJAX fallback\n* Stale-while-revalidate \u2014 Expired cache served instantly while refreshing\n* Per-account WP-Cron background refresh \u2014 All caches stay warm automatically\n* Lean pages \u2014 Only the posts a page can show are built into it; Load more fetches the rest on demand\n* Lazy loading and incremental grid rendering\n* Local picture cache \u2014 Pictures are copied to your uploads folder in three sizes during the background refresh and served from your site with a srcset; a phone loads a 320 px copy instead of Instagram's 2 MB original, visitors' browsers never connect to Meta for pictures, and the gallery survives Instagram's expiring picture links. Can be switched off.\n* Per-IP rate limiting<\/p>\n\n<p><strong>Localization<\/strong>\n* All 30+ frontend strings configurable in admin (translated defaults, override any of them)\n* Relative timestamps and month names customizable<\/p>\n\n<p><strong>Security<\/strong>\n* Bearer token authentication \u2014 API token sent via Authorization header\n* AES-256-CBC token encryption at rest with random IV per encryption\n* CSRF protection \u2014 check_admin_referer() on all admin actions\n* XSS prevention \u2014 gallery built with DOM methods, all output escaped\n* Clean uninstall \u2014 Removes all options, transients, and cron jobs per account<\/p>\n\n<p><strong>Accessibility<\/strong>\n* Full keyboard navigation in lightbox and gallery\n* ARIA labels and screen reader support\n* Respects prefers-reduced-motion<\/p>\n\n<h4>Shortcode<\/h4>\n\n<pre><code>[sdawsoga_gallery]\n<\/code><\/pre>\n\n<h4>Shortcode Attributes<\/h4>\n\n<ul>\n<li><code>account<\/code> \u2014 Account slug from Accounts tab (default: default account)<\/li>\n<li><code>feed_id<\/code> \u2014 Gallery name for CSS targeting<\/li>\n<li><code>limit<\/code> \u2014 Number of posts to display (default: 9)<\/li>\n<li><code>columns<\/code> \u2014 Number of columns (default: 3)<\/li>\n<li><code>layout<\/code> \u2014 grid, masonry, or highlight<\/li>\n<li><code>aspect_ratio<\/code> \u2014 square, portrait, instagram, or original<\/li>\n<li><code>padding<\/code> \u2014 Gap between images in pixels<\/li>\n<li><code>show_header<\/code> \u2014 Show\/hide profile header (true\/false)<\/li>\n<li><code>show_loadmore<\/code> \u2014 Show\/hide load more button (true\/false)<\/li>\n<li><code>hover_effect<\/code> \u2014 Enable\/disable hover overlay (true\/false)<\/li>\n<li><code>filter_type<\/code> \u2014 all, image, video, or carousel<\/li>\n<li><code>hashtag<\/code> \u2014 Only show posts containing this hashtag<\/li>\n<li><code>exclude_hashtags<\/code> \u2014 Comma-separated hashtags to exclude<\/li>\n<li><code>show_stories<\/code> \u2014 Show\/hide Instagram Stories ring (true\/false)<\/li>\n<\/ul>\n\n<h4>Requirements<\/h4>\n\n<ul>\n<li>A Facebook Page connected to an Instagram Business or Creator account<\/li>\n<li>A valid Facebook Page Access Token with the <code>instagram_basic<\/code>, <code>pages_show_list<\/code>, <code>pages_read_engagement<\/code>, and <code>instagram_manage_insights<\/code> permissions (all four are required for the feed)<\/li>\n<li>PHP 7.4+ and WordPress 5.8+<\/li>\n<\/ul>\n\n<h3>Third-Party Services<\/h3>\n\n<p>This plugin connects to the <strong>Instagram Graph API<\/strong> (via Facebook) to retrieve your Instagram posts, profile information, and engagement metrics.<\/p>\n\n<ul>\n<li><strong>Service:<\/strong> Instagram Graph API \/ Facebook Graph API<\/li>\n<li><strong>Website:<\/strong> <a href=\"https:\/\/developers.facebook.com\/\">https:\/\/developers.facebook.com\/<\/a><\/li>\n<li><strong>Terms of Use:<\/strong> <a href=\"https:\/\/developers.facebook.com\/terms\/\">https:\/\/developers.facebook.com\/terms\/<\/a><\/li>\n<li><strong>Privacy Policy:<\/strong> <a href=\"https:\/\/www.facebook.com\/privacy\/policy\/\">https:\/\/www.facebook.com\/privacy\/policy\/<\/a><\/li>\n<\/ul>\n\n<p><strong>When data is sent:<\/strong> When the plugin refreshes the feed cache \u2014 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.<\/p>\n\n<p><strong>What data is sent:<\/strong> 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.<\/p>\n\n<p><strong>Pictures:<\/strong> with the default setting \"Serve pictures from this site\" (Behavior tab), the plugin copies the pictures of your posts to your site's uploads folder during its background refresh, and visitors' browsers load them from your site. Until a picture has been copied, and whenever the setting is off, <strong>pictures are loaded by the visitor's browser directly from Instagram's media servers<\/strong> (cdninstagram.com and fbcdn.net, operated by Meta), as with any embedded Instagram content; Meta then receives the visitor's IP address and browser details for those requests, under the privacy policy linked above. <strong>Videos<\/strong> are always played from Instagram's servers when a visitor starts them, and <strong>Stories<\/strong>, if enabled, are loaded from Instagram's servers. When a visitor opens a gallery page while the cache is empty, the plugin stores a one-way hash of the visitor's IP address for five minutes to limit how often Instagram is contacted. The plugin sets no cookies. A suggested privacy-policy text is provided under Settings \u2192 Privacy \u2192 Policy Guide.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>sdaweb-social-galleri-feed<\/code> folder to <code>\/wp-content\/plugins\/<\/code><\/li>\n<li>Activate the plugin through the Plugins menu<\/li>\n<li>Go to <strong>Social Galleri &gt; Accounts<\/strong> tab<\/li>\n<li>Click <strong>Add Account<\/strong>, enter a label and paste your Facebook Page Access Token<\/li>\n<li>The plugin tests the connection and caches your feed automatically<\/li>\n<li>Add <code>[sdawsoga_gallery]<\/code> to any page or post<\/li>\n<li>For multiple accounts, use <code>[sdawsoga_gallery account=\"slug\"]<\/code><\/li>\n<\/ol>\n\n<p>For token setup instructions, see the built-in setup guide in the Global tab.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"can%20i%20connect%20multiple%20instagram%20accounts%3F\"><h3>Can I connect multiple Instagram accounts?<\/h3><\/dt>\n<dd><p>Yes. Go to the Accounts tab and add up to 20 accounts, each with its own token. Use <code>[sdawsoga_gallery account=\"slug\"]<\/code> to display a specific account. The Shortcode Builder lets you select accounts visually.<\/p><\/dd>\n<dt id=\"why%20do%20likes%20and%20comments%20show%200%3F\"><h3>Why do likes and comments show 0?<\/h3><\/dt>\n<dd><p>The Instagram Graph API only returns engagement metrics for accounts owned by the token holder.<\/p><\/dd>\n<dt id=\"can%20i%20use%20multiple%20feeds%20on%20the%20same%20page%3F\"><h3>Can I use multiple feeds on the same page?<\/h3><\/dt>\n<dd><p>Yes. Use the <code>feed_id<\/code> attribute: <code>[sdawsoga_gallery feed_id=\"homepage\"]<\/code>. Each feed operates independently. Combine with <code>account<\/code> for different accounts: <code>[sdawsoga_gallery account=\"oslo\" feed_id=\"sidebar\"]<\/code>.<\/p><\/dd>\n<dt id=\"how%20do%20i%20change%20the%20language%3F\"><h3>How do I change the language?<\/h3><\/dt>\n<dd><p>Go to <strong>Social Galleri &gt; Translations<\/strong> and update any string.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20page%20builders%3F\"><h3>Does it work with page builders?<\/h3><\/dt>\n<dd><p>Yes. The shortcode works in Elementor, WPBakery, Divi, and any builder that supports WordPress shortcodes. A Gutenberg block is also available.<\/p><\/dd>\n<dt id=\"how%20fast%20does%20the%20feed%20load%3F\"><h3>How fast does the feed load?<\/h3><\/dt>\n<dd><p>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.<\/p><\/dd>\n<dt id=\"what%20facebook%20graph%20api%20permissions%20do%20i%20need%3F\"><h3>What Facebook Graph API permissions do I need?<\/h3><\/dt>\n<dd><p>Four permissions: <code>instagram_basic<\/code>, <code>pages_show_list<\/code>, <code>pages_read_engagement<\/code>, and <code>instagram_manage_insights<\/code>. All four are required for the feed \u2014 the plugin reads your posts through the Graph API Business Discovery endpoint, which needs the insights scope (it is also used by Stories). Omitting <code>instagram_manage_insights<\/code> 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.<\/p><\/dd>\n<dt id=\"can%20i%20extend%20the%20plugin%20from%20my%20theme%20or%20another%20plugin%3F\"><h3>Can I extend the plugin from my theme or another plugin?<\/h3><\/dt>\n<dd><p>Yes. The plugin documents 25 WordPress filter and action hooks covering rendering, post filtering, API data, SEO schema, and lifecycle events; <code>docs\/hooks.md<\/code> 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.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<p>The most recent releases are listed here. The complete history is in changelog.txt in the plugin folder.<\/p>\n\n<h4>6.0.1<\/h4>\n\n<ul>\n<li>Changed: copied pictures are stored as WebP where the server can write it (nearly every host), about a third smaller than the JPEG copies 6.0.0 made, at the same visual quality; JPEG is used where WebP is not available, and the settings page says which. Pictures already copied by 6.0.0 are kept as they are; switch the setting off and on again to rebuild them as WebP.<\/li>\n<li>Changed: album slides, which appear only in the lightbox, are stored in two sizes (640 and 1080 pixels) instead of three, and the copy quality is 80. For an account with many albums the cache is roughly a third smaller again.<\/li>\n<li>Fixed: the settings page quoted a fixed \"about 200 MB\"; it now shows the expected size for each account, computed from the pictures copied so far (an account with 300 posts and many albums has over 1,400 pictures, not the 750 that figure assumed).<\/li>\n<li>Developers: two new filters, <code>sdawsoga_media_cache_slide_sizes<\/code> and <code>sdawsoga_media_cache_mime<\/code>. See docs\/hooks.md.<\/li>\n<\/ul>\n\n<h4>6.0.0<\/h4>\n\n<ul>\n<li>New: pictures are served from your own site. During the background refresh the plugin now copies each post's picture into the uploads folder (wp-content\/uploads\/sdawsoga\/\/) in 320, 640 and 1080 pixel widths, and the gallery loads them from there with a srcset, so a phone gets the 320 px copy. Instagram offers one size only, the full original of 1 to 2.4 MB per picture: on the test site a phone view of 20 posts loaded 14.5 MB of pictures, which this brings down to well under 1 MB. Visitors' browsers no longer connect to Meta for pictures, and the gallery keeps showing pictures after Instagram's signed picture links expire. Copying runs in the background in small batches after each refresh and needs about 200 MB for 300 posts with albums; until a picture has been copied it is shown from Instagram as before. Videos still play from Instagram; their poster picture is cached. The setting \"Serve pictures from this site\" (Behavior tab) is on by default; switching it off deletes the copies. Deleting an account, or the plugin, deletes its copies. Requires the GD or Imagick PHP extension, present on nearly every host; without it the plugin behaves as before and the settings page says so.<\/li>\n<li>Changed: the suggested privacy text and the readme describe the new picture handling, and now mention the five-minute hashed-address marker the rate limiter stores on an empty cache.<\/li>\n<li>Changed: the preconnect hints in the page head point only at hosts the page really loads pictures from; with the picture cache filled there are none.<\/li>\n<li>Developers: two new filters, <code>sdawsoga_media_cache_enabled<\/code> and <code>sdawsoga_media_cache_sizes<\/code>; posts passed to <code>sdawsoga_feed_item<\/code> now carry <code>media_srcset<\/code> (or <code>thumbnail_srcset<\/code> for videos) next to a local address when a copy exists. See docs\/hooks.md.<\/li>\n<li>Also includes the 5.4.1 fixes below, which were not released separately.<\/li>\n<\/ul>\n\n<h4>5.4.1<\/h4>\n\n<ul>\n<li>Security: a malformed request to the feed route (<code>?account[]=x<\/code>) caused a PHP fatal error on PHP 8. Anyone could send it, without logging in, which filled the error log and could set off WordPress's \"technical issue\" email to the site administrator. No data was exposed. The request now gets an ordinary 400 answer.<\/li>\n<li>Fixed: while the feed could not be refreshed (an expired token, an Instagram rate limit), every page view started another Instagram request, even though the next retry was scheduled up to 24 hours later. Page views now leave a failing account alone until its retry, and visitors can start at most one background refresh per account every five minutes. Saving settings still refreshes at once, and any successful fetch ends the waiting period.<\/li>\n<li>Fixed: Load more stopped for good, with no message, when a security plugin or firewall blocked the REST API for visitors: the gallery ended at the posts built into the page. It now falls back to admin-ajax, as the first load already did. If that fails too, the button stays so the visitor can try again, and no posts are skipped.<\/li>\n<li>Fixed: accounts whose label contains an underscore or is long (over 50 characters as a slug) were refused by the REST route, so their galleries also ended at the posts built into the page.<\/li>\n<li>Fixed: the AJAX route returned the raw cached feed, so a post hidden with the <code>sdawsoga_feed_item<\/code> filter could still be fetched there, along with posts without a picture and Instagram's paging cursors. It now answers exactly like the REST route, and also accepts offset and per_page.<\/li>\n<li>Fixed: with the gallery header turned off (<code>show_header=\"false\"<\/code> or the block setting), the lightbox had no profile picture and showed a lone \"@\" before the caption.<\/li>\n<li>Fixed: screen readers read the lightbox picture's description with HTML codes such as <code>&amp;amp;<\/code> and <code>&amp;#39;<\/code> in it.<\/li>\n<li>Fixed: the keyboard focus outline never showed on album dots and the Stories avatar and arrows, because the style rule named classes that do not exist.<\/li>\n<li>Changed: the lightbox arrows' source strings are now English (\"Previous\", \"Next\") instead of Norwegian. Sites without a translation of the plugin will have these two screen-reader labels in English.<\/li>\n<li>Changed: each failed Instagram request is listed once in the plugin's recent errors instead of twice, and a sync that stops partway is now listed too.<\/li>\n<li>Fixed: the \"Enable Lightbox\" and \"Enable Schema\" switches had no effect when turned off: the lightbox still opened and the schema.org data was still written. WordPress hands the settings to the browser as text, and the script compared them with the wrong type.<\/li>\n<li>Fixed: a blocked-words list typed one word per line was saved as a single phrase, so nothing was blocked. Line breaks are kept and read as separators now; commas still work.<\/li>\n<li>Fixed: in the gallery block, \"Show header\" and \"Show Load more\" switched on had no effect when the same setting was off in the plugin settings, although the editor said \"Shown\". The block's own choice now applies either way. If your plugin settings hide the header or the button but a block has the switch on, that block shows them after this update; switch it off in the block to keep them hidden.<\/li>\n<li>Fixed: the Translations help text told you to write \"%1$d\" for the number, which the gallery does not understand; the placeholder is \"%d\".<\/li>\n<li>Fixed: the slide arrows in the lightbox were invisible while a keyboard user had focus on them, and never appeared on touch screens, where there is no hover. They show on focus and are always visible on touch screens.<\/li>\n<li>Fixed: the album dots in the lightbox were 7 pixels wide to tap. The dots look the same but accept a 25-pixel tap, and the current dot is marked for screen readers.<\/li>\n<li>Fixed: a tile growing on hover was clipped by its neighbours along the right and bottom edges.<\/li>\n<li>Changed: the first row of pictures is marked as high priority for the browser, and the row length follows the column count in effect at that screen size instead of the desktop value.<\/li>\n<li>Changed: help texts pointed to an \"API tab\" and a \"Buttons tab\" that do not exist; they name the Accounts and Appearance tabs now.<\/li>\n<\/ul>\n\n<h4>5.4.0<\/h4>\n\n<ul>\n<li>Changed: pages load much faster. A page with a gallery used to carry the complete cached feed of every account \u2014 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.<\/li>\n<li>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.<\/li>\n<li>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 \u2014 or a classroom behind one shared address \u2014 was cut off with an error.<\/li>\n<li>Changed (developers): the <code>sdawsoga_cached_feed_data<\/code> 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 <code>sdawsoga_schema_markup<\/code> 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 <code>sdawsoga_cached_feed_data<\/code>.<\/li>\n<li>Added (developers): four new hooks. <code>sdawsoga_feed_item<\/code> filters one post at a time just before it leaves the server (page and REST route) \u2014 rewrite a picture address or caption, or return false to hide the post; <code>sdawsoga_feed_refreshed<\/code> fires after a fresh feed has been stored, the moment to purge a page cache; <code>sdawsoga_feed_need<\/code> changes what a gallery asks to have inlined; <code>sdawsoga_frontend_config<\/code> filters everything handed to the browser script. All documented in docs\/hooks.md.<\/li>\n<li>Fixed: the gallery block's \"Wide width\", \"Full width\" and HTML anchor settings had no effect on the page \u2014 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\u2026\" 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.<\/li>\n<li>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.<\/li>\n<li>Fixed: the Stories viewer now behaves as a dialog for keyboard and screen-reader users. It is announced as \u201cInstagram Stories\u201d, 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.<\/li>\n<li>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.<\/li>\n<li>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.<\/li>\n<li>Fixed: the gallery's buttons (Load more, lightbox arrows and Close) are now type=\u201cbutton\u201d, so a gallery placed inside a form no longer submits it when they are clicked.<\/li>\n<li>Changed: readme and admin texts brought up to date \u2014 the Third-Party Services section now explains that visitors\u2019 browsers load the pictures from Instagram\u2019s 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 \u201cTools\u201d section is fixed; one outdated entry in the translation template is corrected.<\/li>\n<li>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.<\/li>\n<li>Fixed: the \"Posts label\", \"Followers label\" and \"Profile picture\" fields under Translations had no effect on the gallery header \u2014 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.<\/li>\n<li>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.<\/li>\n<li>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.<\/li>\n<li>Fixed: the lightbox announced itself to screen readers with the \"Post counter\" word from Translations (\"Post\", \"Innlegg\") instead of its name, \"Post viewer\".<\/li>\n<li>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 \u2014 a failing token is not saved and the reason is shown \u2014 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).<\/li>\n<li>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 \u2014 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.<\/li>\n<li>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 \u2014 for example after the Instagram handle was renamed \u2014 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.<\/li>\n<li>Fixed: a field left empty under Translations (or the Follow \/ Load more button text under Appearance) showed nothing at all \u2014 an emptied month name made the lightbox date read \"15. \", an emptied button text left an icon-only button \u2014 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.<\/li>\n<li>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.<\/li>\n<li>Fixed: the hashtag filters matched the start of longer hashtags \u2014 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.<\/li>\n<li>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.<\/li>\n<\/ul>\n\n<h4>5.3.14<\/h4>\n\n<ul>\n<li>Fixed: on sites with a page cache (LiteSpeed Cache, WP Super Cache, Cloudflare \u2026) 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 \u2014 right after adding an account, or while Instagram was unreachable: the security codes in the cached page expire after 12\u201324 hours, and WordPress then refused the gallery's own request. Logged-out visitors no longer send such a code \u2014 the feed is public, read-only data \u2014 so an old cached page keeps working. Nothing changes for logged-in users.<\/li>\n<li>Fixed: after an image failed to load, \"Load more\" showed one post twice.<\/li>\n<li>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.<\/li>\n<li>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 \u2014 the \"error\" text under Translations \u2014 is now shown, and announced to screen readers.<\/li>\n<li>The complete version history has moved to changelog.txt in the plugin folder; this section lists the most recent releases.<\/li>\n<\/ul>\n\n<h4>5.3.13<\/h4>\n\n<ul>\n<li>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.<\/li>\n<li>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 \u2014 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.<\/li>\n<li>Deleting the plugin now also removes the short-lived markers introduced in 5.3.12.<\/li>\n<li>No visible changes and no settings to review.<\/li>\n<\/ul>\n\n<h4>5.3.12<\/h4>\n\n<ul>\n<li>Fix: limit=\"X\" on the shortcode (and \"Posts to show\" in the block) had no effect \u2014 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.<\/li>\n<li>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.<\/li>\n<li>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.<\/li>\n<li>Fix: every apostrophe in a lightbox caption was corrupted \u2014 \"It's\" appeared as \"It&amp;\", a link \"#39\" and \";s\".<\/li>\n<li>Fix: hashtags and mentions with non-English letters were cut at the first such letter \u2014 \"#s\u00f8ndag\" became a link \"#s\" followed by plain \"\u00f8ndag\". Hashtags and mentions are now fully Unicode-aware, email addresses are no longer turned into mentions, and links are URL-encoded.<\/li>\n<li>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 \u2014 twice. A failed fetch is now remembered for five minutes; scheduled refreshes, \"Refresh now\" and \"Clear cache\" are unaffected.<\/li>\n<li>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.<\/li>\n<\/ul>","raw_excerpt":"Display your Instagram feed as a responsive gallery with multi-account support, Stories, lightbox, instant loading, and full admin control.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/es-ar.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/282597","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/es-ar.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/es-ar.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/es-ar.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=282597"}],"author":[{"embeddable":true,"href":"https:\/\/es-ar.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/rstake"}],"wp:attachment":[{"href":"https:\/\/es-ar.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=282597"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/es-ar.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=282597"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/es-ar.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=282597"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/es-ar.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=282597"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/es-ar.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=282597"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/es-ar.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=282597"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}