Main Website Integration
Main Website Integration
The main website at theeducationalequalityinstitute.org is the primary public-facing entry point for TEEI. The chat widget here serves unauthenticated visitors — prospective volunteers, donors, corporate partners, and press.
Prerequisites
@teei/chat-widgetinstalled (see Integration Guide)- TEEI Astro main site set up at
teei-astro/(separate from CSR Cockpit, WBP, Admin) - RAG Worker running at
https://knowledge-api.theeducationalequalityinstitute.org
Key differences from other platforms
| Aspect | Other platforms | Main website |
|---|---|---|
| Authentication | Required | Not required |
| Role | Determined from session | Always public |
| Language | Single language per session | Follows current locale (en / uk / no) |
| Widget scope | Authenticated pages only | Selected pages only (see exclusions) |
Pages where the widget should appear
Show the widget on informational and programme pages. Hide it on transactional pages.
Show on:
- Homepage (
/) - About (
/about/,/about-us/) - Programmes (
/volunteer/,/mentors-for-ukraine/,/language-connect/,/skills-academy/) - Blog landing (
/blog/) — not individual blog posts - Volunteer landing (
/volunteer/,/become-a-volunteer/) - Partnership landing (
/partners/,/for/*) - Contact (
/contact/)
Hide on:
- Individual blog posts (
/blog/[slug]/) — article readers are in reading mode - Donate page (
/donate/) — do not distract during the donation flow - Legal pages (
/privacy-policy/,/terms/,/cookie-policy/) - Thank-you / confirmation pages (
/thank-you/,/confirmed/) - Any page with a long-form lead capture form
Step-by-step installation
Step 1: Identify the main site base layout. The main TEEI website uses several layout files. The base layout (BaseLayout.astro) wraps most public pages.
find teei-astro/src/layouts -name "BaseLayout.astro"Step 2: Add imports to BaseLayout.astro:
---// Existing importsimport SEO from '../components/SEO.astro';
// Add:import { ChatProvider, ChatWidget } from '@teei/chat-widget';import '@teei/chat-widget/styles';
// Determine language from Astro localeconst lang = Astro.currentLocale ?? 'en'; // 'en' | 'uk' | 'no'
// Determine whether to show widget on this pageconst path = Astro.url.pathname;const WIDGET_EXCLUDED_PATHS = [ '/donate/', '/privacy-policy/', '/terms/', '/cookie-policy/', '/thank-you/', '/confirmed/',];const isExcluded = WIDGET_EXCLUDED_PATHS.some(p => path === p || path.startsWith(p)) || /^\/blog\/.+/.test(path); // Individual blog posts (not /blog/ landing)
const showWidget = !isExcluded;---Step 3: Add the widget before </body>:
{showWidget && ( <ChatProvider client:idle apiUrl="https://knowledge-api.theeducationalequalityinstitute.org" platform="website" userRole="public" language={lang} > <ChatWidget greeting="Hi! I'm the TEEI Knowledge Assistant. I can tell you about our volunteering programmes, how to partner with us, and the impact we've made. What would you like to know?" /> </ChatProvider> )}
</body>Step 4: Verify the build. The main site may use a different build command:
cd teei-astronpx astro checknpm run buildStep 5: Verify the widget appears on the correct pages:
# Widget should appear:curl -sI http://localhost:4321/ | head -1 # → 200curl -sI http://localhost:4321/volunteer/ # → 200
# Widget should NOT appear:curl -sI http://localhost:4321/donate/ # → 200 (but no widget)curl -sI http://localhost:4321/blog/some-post/ # → 200 (but no widget)Open the homepage in a browser. The TEEI chat FAB should appear at bottom-right. Navigate to /donate/ — the FAB should be absent.
Multilingual support
The main website supports English (en), Ukrainian (uk), and Norwegian (no). The Astro locale system sets Astro.currentLocale based on the URL prefix (/en/, /uk/, /no/).
The RAG Worker uses the language field to filter content and influence answer language. For example, a query sent with language="uk" will return answers sourced from Ukrainian-tagged content and the AI will respond in Ukrainian.
Ensure content is ingested for each language:
# Ingest English contentnode scripts/ingest.mjs --platform website --language en --dir docs/src/content/docs/en/
# Ingest Ukrainian content (when available)node scripts/ingest.mjs --platform website --language uk --dir docs/src/content/docs/uk/
# Ingest Norwegian content (when available)node scripts/ingest.mjs --platform website --language no --dir docs/src/content/docs/no/Public-role content
Content tagged platform: website and role: public in Vectorize is visible to all widget users — no authentication required. This content should include:
- Programme descriptions (Mentors for Ukraine, Language Connect, WBP, Skills Academy)
- How-to-volunteer guides
- Partnership tier overviews (Connect, Engage, Impact, Strategic)
- About TEEI — mission, impact numbers, countries
- FAQ content
Content that should NOT be tagged for public role:
- Internal processes
- Partner financial details
- Admin procedures
GTM / analytics interaction
The main website uses gtag.js directly (no GTM container after the GTM-W6PB7DK conflict). The chat widget does not fire any Google Ads conversion events. If you want to track widget interactions in GA4, add a custom event using the widget’s DOM events:
// In a <script> tag in BaseLayout.astro:document.addEventListener('click', (e) => { if (e.target.closest('.teei-chat-fab')) { gtag('event', 'chat_widget_open', { platform: 'website' }); }});Do not add the widget to conversion-critical pages (donate, volunteer signup form completion) where it could distract from the primary conversion action.
Verification checklist
-
npx astro checkexits 0 -
npm run buildexits 0 - Chat FAB appears on homepage at 1440px and 375px
- Chat FAB appears on
/volunteer/ - Chat FAB does NOT appear on
/donate/ - Chat FAB does NOT appear on individual blog posts
- Language is
enon English pages,ukon Ukrainian pages (if locales active) - Widget sends
userRole: "public"in API request (check Network tab) - Streamed response received without CORS errors
Gotchas
FundraiseUp widget conflict: The donate page (/donate/) embeds FundraiseUp. Do not add the chat widget to this page — two overlapping FABs create a confusing UI and FundraiseUp has its own z-index claims.
Blog scroll experience: Individual blog posts are long-form reading experiences. The chat widget FAB at position: fixed stays visible while scrolling. On blog posts, this distracts from the content. The exclusion for /blog/[slug]/ is intentional — apply it.
Cookie consent: The main website uses a cookie consent banner. The chat widget does not set cookies. It uses credentials: 'include' for the API request (passes existing session cookies), but does not create new ones. The cookie consent banner should not block the widget.
CORS with credentials: 'include': The RAG Worker returns Access-Control-Allow-Credentials: true and validates the request origin. The main site origin (https://theeducationalequalityinstitute.org) must be in ALLOWED_ORIGINS. It is already included in the default configuration.