Skip to content

docs: add SocialShareButton tutorial video to README#354

Open
sneha-techiee wants to merge 1 commit intoAOSSIE-Org:mainfrom
sneha-techiee:add-social-share-button
Open

docs: add SocialShareButton tutorial video to README#354
sneha-techiee wants to merge 1 commit intoAOSSIE-Org:mainfrom
sneha-techiee:add-social-share-button

Conversation

@sneha-techiee
Copy link
Copy Markdown

@sneha-techiee sneha-techiee commented Apr 14, 2026

Tutorial: SocialShareButton Integration with Resonate Website

Closes #19 (AOSSIE-Org/SocialShareButton)

Added SocialShareButton to the Resonate landing page footer.

🎬 Demo Video: https://drive.google.com/file/d/12gu3D8wuIiDhwZvS12MaiEfg6CFZGTMv/view?usp=sharing

Summary by CodeRabbit

  • New Features

    • Added a styled social share button to the website footer with interactive hover effects.
    • Integrated third-party social sharing library to enable sharing functionality.
  • Documentation

    • Added a "Project Demo" section in the README with a demo video walkthrough.

@sneha-techiee sneha-techiee requested a review from a team as a code owner April 14, 2026 13:12
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 14, 2026

📝 Walkthrough

Walkthrough

The changes integrate a third-party social share button widget into the website. A stylesheet and JavaScript file are loaded in the root layout, the Footer component is converted to a client component with polling logic to initialize the widget when available, and CSS styling is added for the share button.

Changes

Cohort / File(s) Summary
Documentation
README.md
Added a "📺 Project Demo" section linking to a project demo video on Google Drive.
Footer Component & Styling
app/components/Layout/Footer/Footer.css, app/components/Layout/Footer/index.jsx
Added .social-share-btn CSS class with gradient background and hover effects. Converted Footer to client component, imported useEffect, added a 300ms polling interval to detect and instantiate window.SocialShareButton when available, and rendered a #share-button container div.
Root Layout
app/layout.js
Added imports for Next.js Script component and embedded third-party stylesheet link in <head>. Loaded third-party social share button JavaScript with afterInteractive strategy.

Sequence Diagram

sequenceDiagram
    participant Client as Browser/Client
    participant RootLayout as RootLayout
    participant Footer as Footer Component
    participant ThirdParty as Social Share Library

    Client->>RootLayout: Initial page load
    RootLayout->>ThirdParty: Load stylesheet (synchronous)
    RootLayout->>ThirdParty: Load JavaScript (afterInteractive)
    ThirdParty-->>Client: Scripts/styles loaded
    RootLayout->>Footer: Render Footer component
    Footer->>Footer: useEffect hook runs
    Footer->>Footer: Start 300ms polling interval
    loop Poll until available
        Footer->>Client: Check window.SocialShareButton
        alt SocialShareButton exists
            Footer->>ThirdParty: new window.SocialShareButton()
            ThirdParty->>Client: Initialize widget on `#share-button`
            Footer->>Footer: Clear polling interval
        end
    end
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

Poem

🐰 A social share button hops into view,
Through polling and scripts, the magic shines true,
With gradients and hovers, styled just right,
The widget awakens—connectivity's flight! ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 4

❌ Failed checks (4 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title describes adding a tutorial video to README, but the actual changes include integrating SocialShareButton into the footer component with CSS, layout modifications, and third-party script loading—significantly broader scope than just documentation. Update title to reflect the full scope: e.g., 'feat: add SocialShareButton integration to footer with tutorial video' or similar.
Linked Issues check ⚠️ Warning The linked issue #19 requests mobile-responsive navigation with hamburger menu, keyboard accessibility, and animations, but the PR implements SocialShareButton integration—a completely unrelated feature with no navigation responsive design changes. Either implement the mobile-responsive navigation requirements from issue #19, or verify that the correct linked issue for SocialShareButton integration is referenced instead.
Out of Scope Changes check ⚠️ Warning All code changes (Footer component, CSS, layout script loading) implement SocialShareButton functionality, which is out of scope for the linked issue #19 about mobile-responsive navigation. Remove the incorrect issue link or reopen/reference the correct issue that covers SocialShareButton feature implementation.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
app/components/Layout/Footer/Footer.css (1)

73-86: Prefer scoped selectors over repeated !important overrides.

Using !important on most properties will make future styling and theming harder. Scope the rule to the mount container (for example #share-button .social-share-btn) and drop the debug-style comment.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/Layout/Footer/Footer.css` around lines 73 - 86, The rule
currently forces styles with multiple !important flags and a debug comment;
instead scope the selector to the mounting container (e.g., use a parent id like
`#share-button` .social-share-btn) and remove the debug comment and all !important
declarations so normal cascade and theming work; update both the base selector
(.social-share-btn) and the hover selector (.social-share-btn:hover) to the
scoped form and keep the same properties (background, border, color, padding,
border-radius, cursor, box-shadow) but without !important.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/components/Layout/Footer/index.jsx`:
- Around line 15-16: The share payload in Layout/Footer/index.jsx currently
hardcodes url: "https://aossie.org" and title: "Check out AOSSIE!" so shares
point to the wrong site; locate the share payload object in the Footer component
and replace those hardcoded values with runtime page metadata (use
window.location.href and document.title), guarding for SSR by checking typeof
window !== 'undefined' and falling back to sensible defaults (e.g., site home
URL and a default title) so the share uses the current page URL and title when
available.
- Around line 10-22: The useEffect polling loop that creates new
window.SocialShareButton (uses interval variable inside useEffect) can run
indefinitely if the external script never loads; modify the effect to add a
retry cap and a timeout: track attempts (e.g., maxAttempts) or an elapsed start
time inside the effect, increment attempts each tick and clearInterval(interval)
and stop trying once the cap/time is reached, and optionally log or show a
failure; keep the existing creation code that instantiates new
window.SocialShareButton({ container: "#share-button", url: "...", title: "..."
}) but only call it when window.SocialShareButton exists and ensure cleanup
still clears the interval in all terminal cases.

In `@app/layout.js`:
- Around line 31-34: The external jsDelivr assets are missing SRI and
crossorigin attributes; update the <link> element that loads
"https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.css"
and the Next.js <Script> component that loads the matching .js to include
integrity="sha384-<calculated-hash>" and crossOrigin="anonymous". Generate the
SRI value by downloading each asset and computing the base64 sha384 digest (curl
-s <url> | sha384sum | xxd -r -p | base64) and plug that result into the
integrity attribute, keeping the same src and strategy props on the <Script>
component.

In `@README.md`:
- Around line 18-22: The README's Project Demo documents SocialShareButton but
references Issue `#19` (mobile navigation) — remove any auto-closing keywords or
issue-closing syntax and clarify linkage: in the "Project Demo" /
SocialShareButton note, replace any phrasing like "fixes `#19`" or "closes `#19`"
with "related to Issue `#19`" and add a short line that mobile navigation
(hamburger/menu accessibility) is not implemented here; also update the PR
description to avoid auto-closing Issue `#19` and explicitly state that the mobile
nav requirements remain outstanding. Ensure references point to
SocialShareButton and Issue `#19` (mobile navigation / hamburger/menu
accessibility) so reviewers can locate the discrepancy.

---

Nitpick comments:
In `@app/components/Layout/Footer/Footer.css`:
- Around line 73-86: The rule currently forces styles with multiple !important
flags and a debug comment; instead scope the selector to the mounting container
(e.g., use a parent id like `#share-button` .social-share-btn) and remove the
debug comment and all !important declarations so normal cascade and theming
work; update both the base selector (.social-share-btn) and the hover selector
(.social-share-btn:hover) to the scoped form and keep the same properties
(background, border, color, padding, border-radius, cursor, box-shadow) but
without !important.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 30ae8c1a-cbe5-4ad7-a27d-43d4fc44b018

📥 Commits

Reviewing files that changed from the base of the PR and between ee40ec9 and 1842e0c.

📒 Files selected for processing (4)
  • README.md
  • app/components/Layout/Footer/Footer.css
  • app/components/Layout/Footer/index.jsx
  • app/layout.js

Comment on lines +10 to +22
useEffect(() => {
const interval = setInterval(() => {
if (typeof window !== "undefined" && window.SocialShareButton) {
new window.SocialShareButton({
container: "#share-button",
url: "https://aossie.org",
title: "Check out AOSSIE!"
});
clearInterval(interval);
}
}, 300);
return () => clearInterval(interval);
}, []);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Polling is unbounded if the external script never becomes available.

If window.SocialShareButton never loads, the interval keeps running for the component lifetime. Add a retry cap/timeout and fail fast.

Proposed reliability fix
 useEffect(() => {
-  const interval = setInterval(() => {
+  let attempts = 0;
+  const maxAttempts = 20; // ~6s at 300ms
+  const interval = setInterval(() => {
+    attempts += 1;
     if (typeof window !== "undefined" && window.SocialShareButton) {
       new window.SocialShareButton({
         container: "#share-button",
         url: "https://aossie.org", 
         title: "Check out AOSSIE!"
       });
       clearInterval(interval);
+      return;
     }
+    if (attempts >= maxAttempts) clearInterval(interval);
   }, 300);
   return () => clearInterval(interval);
 }, []);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
const interval = setInterval(() => {
if (typeof window !== "undefined" && window.SocialShareButton) {
new window.SocialShareButton({
container: "#share-button",
url: "https://aossie.org",
title: "Check out AOSSIE!"
});
clearInterval(interval);
}
}, 300);
return () => clearInterval(interval);
}, []);
useEffect(() => {
let attempts = 0;
const maxAttempts = 20; // ~6s at 300ms
const interval = setInterval(() => {
attempts += 1;
if (typeof window !== "undefined" && window.SocialShareButton) {
new window.SocialShareButton({
container: "#share-button",
url: "https://aossie.org",
title: "Check out AOSSIE!"
});
clearInterval(interval);
return;
}
if (attempts >= maxAttempts) clearInterval(interval);
}, 300);
return () => clearInterval(interval);
}, []);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/Layout/Footer/index.jsx` around lines 10 - 22, The useEffect
polling loop that creates new window.SocialShareButton (uses interval variable
inside useEffect) can run indefinitely if the external script never loads;
modify the effect to add a retry cap and a timeout: track attempts (e.g.,
maxAttempts) or an elapsed start time inside the effect, increment attempts each
tick and clearInterval(interval) and stop trying once the cap/time is reached,
and optionally log or show a failure; keep the existing creation code that
instantiates new window.SocialShareButton({ container: "#share-button", url:
"...", title: "..." }) but only call it when window.SocialShareButton exists and
ensure cleanup still clears the interval in all terminal cases.

Comment on lines +15 to +16
url: "https://aossie.org",
title: "Check out AOSSIE!"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Share payload is hardcoded to a different site.

The widget currently shares https://aossie.org instead of the active Resonate page. Use runtime page metadata (window.location.href, document.title) so shares reflect what the user is viewing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/Layout/Footer/index.jsx` around lines 15 - 16, The share
payload in Layout/Footer/index.jsx currently hardcodes url: "https://aossie.org"
and title: "Check out AOSSIE!" so shares point to the wrong site; locate the
share payload object in the Footer component and replace those hardcoded values
with runtime page metadata (use window.location.href and document.title),
guarding for SSR by checking typeof window !== 'undefined' and falling back to
sensible defaults (e.g., site home URL and a default title) so the share uses
the current page URL and title when available.

Comment thread app/layout.js
Comment on lines +31 to +34
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.css"
/>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

css_url="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.css"
js_url="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.js"

for url in "$css_url" "$js_url"; do
  echo "URL: $url"
  hash=$(curl -fsSL "$url" | openssl dgst -sha384 -binary | openssl base64 -A)
  echo "integrity=\"sha384-$hash\""
  echo
done

Repository: AOSSIE-Org/Resonate-Website

Length of output: 327


🏁 Script executed:

cat -n app/layout.js | sed -n '25,55p'

Repository: AOSSIE-Org/Resonate-Website

Length of output: 905


🏁 Script executed:

# Search for all external CDN links in the layout file
rg 'href=|src=' app/layout.js -A 2 -B 1

Repository: AOSSIE-Org/Resonate-Website

Length of output: 406


🏁 Script executed:

# Try to fetch the CSS/JS files and generate SRI using Python
python3 << 'EOF'
import hashlib
import base64
import urllib.request

urls = [
    "https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.css",
    "https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.js"
]

for url in urls:
    try:
        with urllib.request.urlopen(url, timeout=10) as response:
            content = response.read()
            hash_obj = hashlib.sha384(content)
            integrity = "sha384-" + base64.b64encode(hash_obj.digest()).decode('ascii')
            print(f"URL: {url}")
            print(f'integrity="{integrity}"')
            print()
    except Exception as e:
        print(f"Error fetching {url}: {e}")
        print()
EOF

Repository: AOSSIE-Org/Resonate-Website

Length of output: 555


🌐 Web query:

Next.js Script component integrity attribute SRI support

💡 Result:

The Next.js Script component (next/script) does not have a built-in integrity prop listed in the official documentation. Official docs for Script component props include src, strategy, onLoad, onReady, onError, etc., but no integrity. However, it supports additional arbitrary HTML attributes (like nonce, data-), which are forwarded to the underlying <script> element. You can manually add integrity="sha256-..." to external third-party scripts for SRI support. Next.js has experimental.sri support (next.config.js: experimental: { sri: { algorithm: 'sha256' } }) that automatically adds integrity attributes to its own internal static chunks (e.g., _next/static/chunks/) in App Router builds, generating a subresource-integrity-manifest.json. This works for Node.js and Edge runtimes but has limitations: missing for some client chunks ('use client'), stylesheets, and mismatches with CDN compression (open issues as of 2026). It does not apply to Script component-loaded third-party scripts. For complete SRI: - Manual for third-party via Script: <Script src="..." integrity="sha256-ABC123" crossorigin="anonymous" /> - Automatic (experimental, incomplete) for Next.js bundles via config.

Citations:


Add SRI integrity attributes to third-party CDN assets.

External CSS and JavaScript from jsdelivr are loaded without integrity verification, creating a supply-chain risk. Add integrity attributes (with corresponding SRI hash) and crossOrigin="anonymous" to both the <link> tag (lines 31-34) and the <Script> component (lines 43-46). The Next.js <Script> component supports arbitrary HTML attributes, so integrity can be passed directly:

Example for Script component
<Script
  src="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.js"
  integrity="sha384-[hash-here]"
  crossOrigin="anonymous"
  strategy="afterInteractive"
/>

Generate SRI hashes using: curl -s <url> | sha384sum | xxd -r -p | base64

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/layout.js` around lines 31 - 34, The external jsDelivr assets are missing
SRI and crossorigin attributes; update the <link> element that loads
"https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.css"
and the Next.js <Script> component that loads the matching .js to include
integrity="sha384-<calculated-hash>" and crossOrigin="anonymous". Generate the
SRI value by downloading each asset and computing the base64 sha384 digest (curl
-s <url> | sha384sum | xxd -r -p | base64) and plug that result into the
integrity attribute, keeping the same src and strategy props on the <Script>
component.

Comment thread README.md
Comment on lines +18 to +22
## 📺 Project Demo

Watch the Resonate Website in action with SocialShareButton:
[**Project Demo Video**](https://drive.google.com/file/d/12gu3D8wuIiDhwZvS12MaiEfg6CFZGTMv/view?usp=sharing)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

PR closure target appears mismatched with linked issue objective.

This change documents SocialShareButton, but the linked Issue #19 objective is mobile navigation (hamburger/menu accessibility). Please avoid auto-closing that issue from this PR unless the nav requirements are implemented here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 18 - 22, The README's Project Demo documents
SocialShareButton but references Issue `#19` (mobile navigation) — remove any
auto-closing keywords or issue-closing syntax and clarify linkage: in the
"Project Demo" / SocialShareButton note, replace any phrasing like "fixes `#19`"
or "closes `#19`" with "related to Issue `#19`" and add a short line that mobile
navigation (hamburger/menu accessibility) is not implemented here; also update
the PR description to avoid auto-closing Issue `#19` and explicitly state that the
mobile nav requirements remain outstanding. Ensure references point to
SocialShareButton and Issue `#19` (mobile navigation / hamburger/menu
accessibility) so reviewers can locate the discrepancy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mobile-Friendly Responsive Navigation

1 participant