Skip to main content
Віджет Ayrshare Connect розміщує наші кнопки зв’язування всередині вашої власної панелі керування. Ви завантажуєте один скрипт, ставите слот там, де мережа має бути у вашому макеті, і ми рендеримо там кнопку, яка вже показує, чи підключено акаунт. Ваш користувач натискає її і зв’язує акаунт, не залишаючи вашої сторінки — щонайбільше одне спливаюче вікно, і то власне вікно мережі. Ви не пишете обробку спливаючих вікон, OAuth-колбеки, оновлення сесії чи логіку для кожної мережі. Коли мережа щось змінює на своєму боці, виправлення з’являється всередині наших фреймів у момент нашого деплою; ви нічого не редеплоїте.

Яка поверхня вам потрібна

Клієнтська панель керування з плитками Ayrshare Connect для Instagram, TikTok і LinkedIn, вбудованими в картку

Вбудовані фрейми: наші плитки, відрендерені всередині вашого власного макета — один слот на мережу або один слот на кілька мереж.

Клієнтська панель керування з власними кнопками Connect і спливаючим вікном Ayrshare з екраном передачі Facebook

Ваша власна кнопка: ви рендерите кнопку, а одне коротке наше спливаюче вікно опрацьовує мережу.

Хостована сторінка соціального зв'язування, що показує всі доступні мережі

Хостована сторінка зв'язування: сторінка, яку хостимо ми, з вашим логотипом і кольорами, заради якої ваш користувач залишає ваш застосунок.

Два рядки з віджетом — це одна інтеграція, а не дві. Один init дає обидва варіанти: монтуйте фрейми там, де мають бути наші кнопки, і викликайте popup() з власної кнопки всюди інде. Вони ділять одну сесію і звітують через ті самі обробники.Прямий режим (Direct Mode) — це те саме спливаюче вікно, але без нашого скрипта — для сторінки із суворою Content-Security-Policy, сторінки з серверним рендерингом або нативного застосунку. Там ви відкриваєте спливаюче вікно й стежите за ним самостійно.

Додайте скрипт

Зафіксуйте версію та її хеш або слідкуйте за каналом без нього. Ніколи не робіть обох одразу — атрибут integrity на рухомому URL перестає працювати з нашим наступним релізом, бо файл, який він називає, легітимно змінився.
Pinned version
Tracking v1
v1 — канал, який варто рекомендувати. Він підхоплює виправлення, але ніколи не перетинає злам сумісності. latest перетинає мажорні версії за визначенням, тож він зрештою підсуне вашій сторінці версію, поведінку якої ви не переглядали. Хеш кожної версії опубліковано в manifest.json, який також називає, що саме зараз обслуговує кожен канал:
manifest.json
Кожен бандл також починається з коментаря з назвою власної версії — це найшвидший спосіб сказати нам, що насправді виконує сторінка:

Content-Security-Policy

Якщо ваша сторінка надсилає Content-Security-Policy, їй потрібні два записи, обидва з хостом, з якого ви завантажуєте скрипт:
Це весь список. Вам не потрібен запис connect-src для нас — наші фрейми звертаються до нашого API зсередини себе, а не з вашої сторінки — і жодного запису для спливаючих вікон, які є вікнами верхнього рівня, що не підпадають під вашу політику. Обидва записи перевірено вимірюванням: вилучення script-src блокує скрипт, а вилучення frame-src блокує фрейм.

Запустіть екземпляр

session — єдиний обов’язковий параметр. Він викликається один раз на екземпляр, а не один раз на кожен mount, і має повернути відповідь вашого бекенду на Створення Link Session з mode: "connect" — { sessionId, token, expiresAt } — точно такою, якою вона надійшла.
Your page
Your backend
Сесія віджета не називає network — вона авторизує кожну мережу, яку дозволяє ваш акаунт, а які з них з’являться, вирішується для кожного mount, на вашій сторінці. Вона несе origin, і саме він робить рендеринг фреймів взагалі можливим: фрейм звіряє сторінку, що його вбудувала, з цим значенням і відмовляється рендеритися будь-де інде.
Створюйте сесію на своєму сервері. Виклик потребує вашого API Key, а повернений токен авторизує вашого користувача в його User Profile — ставтеся до нього як до пароля.
Ми викликаємо session знову до закінчення строку дії токена, тож віджет продовжує працювати на сторінці, залишеній відкритою на весь день. Виклик, який завершується відмовою або не повертає токен, повторюється ще двічі — через 0,5 с, потім через 1 с — перш ніж ми здаємося і генеруємо error. Тож одне оновлення коштує щонайбільше трьох викликів вашого ендпоінта.

Змонтуйте слот

Один mount на слот. Запитуйте одну мережу, кілька або все, що дозволяє сесія — гранулярність за вами, тож слот може бути одним рядком у наявній таблиці або однією панеллю, що вміщує все.
mount приймає CSS-селектор або елемент і повертає { unmount, element }. Він кидає виняток, якщо ціль нічому не відповідає — це майже завжди слот, якого ще не існує, тож монтуйте після того, як ваша розмітка опиниться в документі. Кожен mount — це один iframe. Він повідомляє нам власну висоту, і ми змінюємо його розмір відповідно, тож ваш макет перебудовується разом зі зміною нашого вмісту; після maxHeight фрейм прокручується всередині замість того, щоб вилазити за межі вашої сторінки. Найвужчий слот, який ми підтримуємо, — 300px. Ключі мереж — власні ключі Ayrshare, і альтернативні написання теж працюють: instagram та instagramapi обидва означають instagramApi, а x означає twitter. Ключ, який не є мережею, не рендерить жодної плитки.

Ваша власна кнопка

Клієнт, який радше використає власну кнопку, ніж один із наших фреймів, викликає натомість popup. Він запускає той самий потік, у тій самій сесії, і звітує через ті самі обробники.
Викликайте його безпосередньо всередині обробника кліку, без жодного await перед ним. Браузер дозволяє спливаюче вікно, лише поки він ще опрацьовує клік вашого користувача, і цей дозвіл не переживає await. Втім, чекати й нема чого — сесію було створено під час init.
popup повертає { close(), network } і завжди повертає handle — навіть після заблокованого спливаючого вікна, де close() нічого не робить — тож вашому коду ніколи не доводиться перевіряти його на null перед викликом close(). Тут працює кожна мережа, включно з тими, які фрейм завершує всередині власної панелі: Facebook показує свій екран-пояснення передачі у спливаючому вікні, Bluesky і X показують свою форму облікових даних, а LinkedIn, Pinterest, YouTube і Google Business виходять до мережі й повертаються. Він синхронно кидає виняток для трьох речей, які є помилками програмування — відсутній network, знищений екземпляр або сесія, яка ще не розв’язалася. Заблоковане спливаюче вікно не одна з них: воно генерує error з reason: "popupBlocked", бо ваш користувач не зробив нічого поганого. Одночасно відкрите щонайбільше одне спливаюче вікно. Другий виклик закриває перше й повідомляє на ньому cancelled з reason: "superseded". Спливаюче вікно, відкрите одним із наших фреймів, — інша річ, і його ніколи не чіпають, тож ваша кнопка не може скасувати потік, що виконується всередині змонтованого слота.
Чи може сесія зв’язати мережу — це відповідь сервера, а не скрипта. Сесія, обмежена Bluesky, яку попросили про LinkedIn, отримує відмову, відрендерену у спливаючому вікні й повідомлену як error. Скрипт перевіряє лише те, що мережу взагалі назвали.

React

Скрипт не залежить від фреймворків, тож React не потребує від нас нічого особливого — але чотири речі про його життєвий цикл варто зробити правильно з першого разу. Завантажуйте скрипт один раз, поза деревом ваших компонентів. У Next.js це next/script у кореневому layout; у Vite або Create React App це тег в index.html. Завантаження у кожному компоненті перезапускає його при кожному монтуванні.
ConnectAccounts.jsx
Ніколи не використовуйте екземпляр повторно після destroy(). Знищений екземпляр залишається знищеним — popup() на ньому кидає виняток, а mount() його не поверне. Створіть новий екземпляр у наступному запуску ефекту, що й робить код вище.
Два наслідки цього патерну, і жоден із них не є багом:
  • У розробці ви побачите, що колбек session спрацьовує двічі. Strict Mode у React виконує ефекти в порядку mount → unmount → mount, тож екземпляр створюється, знищується і створюється знову. Наведене вище очищення робить це безпечним; це коштує одного додаткового виклику вашого бекенду в dev і жодного в production.
  • Тримайте залежності ефекту стабільними. Літерал масиву, переданий прямо в mount з рендера батьківського компонента, — це щоразу нове значення, тож ефект, який від нього залежить, розбирає віджет і перебудовує його при кожному рендері. Мемоізуйте його або тримайте константою, як вище.

Події

Підписуйтеся через on, який повертає функцію відписки. Обробники отримують payload події та mount, з якого вона надійшла; off(name, handler) робить ту саму роботу, коли ви радше назвете обробник.
Десять подій. Кожна несе network, крім ready і крім того одного різновиду error, який взагалі не про мережу — див. error має два джерела нижче. Чотири з них — завершення — success, unlinked, error і cancelled — і рівно одне надходить на кожну спробу. closed — це повідомлення життєвого циклу, яке йде слідом за завершенням, а не є ним. click спрацьовує до початку будь-якої роботи зі зв’язування, тож він повідомляє про клік, який заблоковане спливаюче вікно або мертва сесія згодом відхилить. Це подія для вашої власної аналітики; started — та, що означає, що спроба справді виконується.

Причини

error має два джерела

Лише одне з них — невдале зв’язування, і вони несуть різні поля.
  • Помилка зв’язування несе network, code і mount, з якого вона надійшла.
  • Помилка сесії — ми не змогли створити або оновити вашу сесію — несе лише message, бо в той момент нічого не зв’язувалося.
Деструктуруйте обережно: code і network — undefined у другому різновиді.

state позбавляє вас опитування

state — це канал даних, а не звіт про спробу. Кожен фрейм генерує одну подію на мережу при монтуванні, з поточним станом цієї мережі й міткою часу since, від якої вона його тримає, і ще одну щоразу, коли стан змінюється — включно зі змінами, що походять з нашого боку, наприклад коли токен помирає у стан «потрібне повторне зв’язування». Тож ви можете керувати всім своїм UI з віджета, нічого не опитуючи. Значення — той самий перелік, який повертає GET /profiles з include=state: linked, unlinked, identityVerificationRequired, restricted, rateLimited, suspended.

Від’єднання

Наші плитки не лише зв’язують, а й від’єднують. Ваш користувач натискає підключену мережу, підтверджує, і акаунт видаляється:
  1. Спрацьовує click з action: "unlink".
  2. Спрацьовує unlinked, щойно видалення збережено.
Від’єднання, яке зазнало невдачі, повідомляє error, а те, від якого ваш користувач відмовився на кроці підтвердження, повідомляє cancelled. Окремої події «від’єднання не вдалося» немає.

Зовнішній вигляд

Таблиця стилів клієнта не може дістатися всередину крос-доменного фрейма, тож стилізація подорожує як дані, які ми застосовуємо всередині нього. Передайте appearance в init як користувацькі властивості CSS; кожна, якої ми не отримали, зберігає наше стандартне значення.
Задавайте кольори парами. Токен фону без токена переднього плану поруч — єдиний спосіб отримати щось нечитабельне: задайте --ayr-connect-surface-bg темним значенням самим по собі, і наш стандартний --ayr-connect-surface-fg усе ще буде темно-синім. Ніщо не може вивести другу половину за вас.
Без жодного appearance кожен токен тримає своє стандартне значення, і фрейм виглядає так:
Три плитки Ayrshare Connect зі стандартним виглядом

Стандартні токени: білі поверхні, темно-синій текст, акцент індиго, радіус 8px.

Передайте жменьку токенів — і той самий фрейм набуває вашої палітри. Цей приклад робить поверхні блідо-блакитними, поглиблює текст і акцент відповідно й трохи більше заокруглює кути:
Три плитки Ayrshare Connect, перестилізовані з блідо-блакитними поверхнями й глибшим синім акцентом

Ті самі три плитки після застосування наведених вище токенів.

Є одна палітра й жодного світлого/темного пресета. Ніщо не орієнтується на prefers-color-scheme — навмисно: тема вашої сторінки може не збігатися з операційною системою вашого користувача, і media query мовчки переголосувала б кольори, які ви обрали. Темна панель керування отримує тему через темні значення. Цей список токенів — підтримуваний контракт, який ми зберігаємо між версіями.

Токени

Значення, яке не є валідним CSS для свого токена, ігнорується з попередженням у вашій консолі, а не застосовується. Це важливіше, ніж звучить: 8 без одиниць виміру для --ayr-connect-spacing — цілком безневинний рядок, який зробив би недійсним кожне обчислення, що його читає, і зруйнував би макет без жодної помилки будь-де. Давайте довжинам одиниці виміру.

Ваша власна назва на екрані передачі

Перш ніж передати вашого користувача мережі, ми показуємо короткий екран із назвою того, через кого він підключається. Два гачки дозволяють зробити його вашим власним, і обидва стабільні між версіями. --ayr-connect-partner-name задає підпис. Це єдиний токен, значення якого — текст, тож його треба брати в лапки як рядок CSS — значення без лапок недійсне і не рендерить взагалі нічого:
Логотип — не токен. Ми постачаємо знак як позиціонований елемент із заданим розміром, а ви заповнюєте його через background-image у css, як вище — токен, який міг би завантажити зображення зсередини нашого документа, ми не приймаємо, тож запит походить із правила, яке написали ви, а не зі значення, яке ви нам передали.
[data-ayr-connect-partner-mark] і [data-ayr-connect-partner-name] — виняток із застереження про власний CSS нижче: ці два селектори є частиною контракту, і ми зберігаємо їх між версіями.

Власний CSS

css приймає рядок, застосовуваний всередині кожного фрейма, для випадків, які токени не покривають.
Власний CSS не підтримується між версіями. Його селектори орієнтуються на нашу внутрішню розмітку, яка змінюється між релізами — правило, що працює сьогодні, може мовчки перестати збігатися після будь-якого оновлення. Контракт токенів вище — та частина, яку ми зберігаємо. Зафіксуйте версію, якщо ви залежите від власного CSS.
Спливаючі вікна успадковують appearance і css екземпляра точно так само, як фрейми, тож ваш користувач не спостерігає, як наші нейтральні стандартні стилі з’являються посеред потоку.

Варто знати перед випуском

Спливаючому вікну, відкритому через popup(), не можна сказати, чому токен було відхилено — щоб це зробити, воно мало б довіритися origin, який ще не валідувало, чого наша модель безпеки не дозволяє. Тож спливаюче вікно з мертвим токеном закривається і проявляється як cancelled з reason: "popupClosed", а не error.На практиці це рідкість: спливаюче вікно, відкрите до тихого оновлення, продовжує працювати, бо валідувало свій токен під час відкриття. Якщо ви бачите незрозумілі результати popupClosed, перевірте, що ваш ендпоінт session повертає свіжу сесію.
Чотирнадцять mount ділять один токен і коштують один виклик вашого бекенду, а не чотирнадцять. Якщо вам потрібні слоти з різними межами — інший allowedSocial на деяких із них — запустіть другий init із власною сесією, а не очікуйте, що mount її звузить.
Кожна сесія несе origin, на якому працює ваша сторінка, і фрейм звіряє сторінку, що його вбудувала, з цим значенням, перш ніж щось рендерити. Фрейм, вбудований деінде, залишається порожнім і не надсилає жодних подій. Немає allowlist для реєстрації і нічого налаштовувати — надішліть правильний origin під час створення сесії.
Фрейми повідомляють свою висоту скрипту, і скрипт змінює їхній розмір. Ваш макет просто перебудовується. Немає події resize, на яку можна підписатися, і нічого вимірювати на вашому боці.

Вимоги

  • Max Pack. Сесія віджета — це сесія в режимі connect, і її створення без Max Pack повертає code: 504. Зверніться до підтримки, якщо вам потрібно ввімкнути режим connect на акаунті без нього.
  • origin на кожній сесії — точний origin, на якому працює ваша сторінка. Його пропуск повертає code: 505; значення, яке не є origin https, власною схемою або http://localhost, повертає code: 506.
  • Без network на сесії. Саме цей параметр робить сесію натомість прямим режимом, а URL сесії прямого режиму — не те, чого очікує скрипт.
Кожен наведений вище код є в довіднику Помилки Link Session, з точним повідомленням, яке повертає API, і тим, що з цим робити.