Embed X (Twitter) timelines in your Angular 20+ applications with ease. Built as a standalone component using modern Angular features including signals and effects.
- Features
- Demo
- Installation
- Quick Start
- Usage Examples
- API Reference
- Migration Guide
- Troubleshooting
- Contributing
- License
- ✅ Angular 20+ - Built for the latest Angular version
- ✅ Standalone Component - No NgModule required
- ✅ Signal Inputs - Modern reactive programming
- ✅ TypeScript - Full type safety with strict typing
- ✅ Tree-shakeable - Optimized bundle size
- ✅ SSR Compatible - Works with Angular Universal
- ✅ Customizable - Theme, size, and language options
- ✅ X Platform Updated - Compatible with latest X API changes
Live Demo: https://angular-twitter-timeline.stackblitz.io
Interactive Editor: https://stackblitz.com/edit/angular-twitter-timeline
Install the package via npm:
npm install angular-twitter-timelineOr using yarn:
yarn add angular-twitter-timelineOr using pnpm:
pnpm add angular-twitter-timeline- Angular 20.0.0 or higher
- TypeScript 5.8 or higher
import { Component } from '@angular/core';
import { AngularTwitterTimelineComponent } from 'angular-twitter-timeline';
@Component({
selector: 'app-root',
standalone: true,
imports: [AngularTwitterTimelineComponent],
template: `
<angular-twitter-timeline
[data]="{sourceType: 'profile', screenName: 'mustafaer_dev'}"
[opts]="{height: 600, theme: 'light'}">
</angular-twitter-timeline>
`
})
export class AppComponent {}If you're using NgModules:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AngularTwitterTimelineComponent } from 'angular-twitter-timeline';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
AngularTwitterTimelineComponent // Import as standalone
],
bootstrap: [AppComponent]
})
export class AppModule {}Display a user's timeline by their screen name:
import { Component } from '@angular/core';
import { AngularTwitterTimelineComponent } from 'angular-twitter-timeline';
@Component({
selector: 'app-profile-timeline',
standalone: true,
imports: [AngularTwitterTimelineComponent],
template: `
<angular-twitter-timeline
[data]="timelineData"
[opts]="timelineOptions">
</angular-twitter-timeline>
`
})
export class ProfileTimelineComponent {
timelineData = {
sourceType: 'profile' as const,
screenName: 'mustafaer_dev'
};
timelineOptions = {
theme: 'light' as const,
height: 600
};
}Display a timeline from a specific URL with custom styling:
import { Component } from '@angular/core';
import { AngularTwitterTimelineComponent } from 'angular-twitter-timeline';
@Component({
selector: 'app-url-timeline',
standalone: true,
imports: [AngularTwitterTimelineComponent],
template: `
<angular-twitter-timeline
[data]="timelineData"
[opts]="timelineOptions">
</angular-twitter-timeline>
`
})
export class UrlTimelineComponent {
timelineData = {
sourceType: 'url' as const,
url: 'https://twitter.com/angular'
};
timelineOptions = {
theme: 'dark' as const,
height: 500,
width: 400
};
}Display a timeline with custom language and responsive width:
import { Component } from '@angular/core';
import { AngularTwitterTimelineComponent } from 'angular-twitter-timeline';
@Component({
selector: 'app-responsive-timeline',
standalone: true,
imports: [AngularTwitterTimelineComponent],
template: `
<angular-twitter-timeline
[data]="timelineData"
[opts]="timelineOptions">
</angular-twitter-timeline>
`
})
export class ResponsiveTimelineComponent {
timelineData = {
sourceType: 'profile' as const,
screenName: 'typescript'
};
timelineOptions = {
theme: 'light' as const,
height: 700,
lang: 'en' // BCP 47 language code
};
}Use Angular signals for reactive timeline updates:
import { Component, signal } from '@angular/core';
import { AngularTwitterTimelineComponent } from 'angular-twitter-timeline';
@Component({
selector: 'app-dynamic-timeline',
standalone: true,
imports: [AngularTwitterTimelineComponent],
template: `
<div>
<button (click)="toggleTheme()">Toggle Theme</button>
<angular-twitter-timeline
[data]="timelineData()"
[opts]="timelineOptions()">
</angular-twitter-timeline>
</div>
`
})
export class DynamicTimelineComponent {
timelineData = signal({
sourceType: 'profile' as const,
screenName: 'mustafaer_dev'
});
timelineOptions = signal({
theme: 'light' as const,
height: 600
});
toggleTheme() {
const current = this.timelineOptions();
this.timelineOptions.set({
...current,
theme: current.theme === 'light' ? 'dark' : 'light'
});
}
}<angular-twitter-timeline [data]="..." [opts]="..."></angular-twitter-timeline>| Property | Type | Required | Description |
|---|---|---|---|
data |
AngularTwitterTimelineDataInterface |
Yes | Timeline data configuration |
opts |
AngularTwitterTimelineOptionsInterface |
No | Timeline display options |
Configure what timeline to display:
interface AngularTwitterTimelineDataInterface {
sourceType: 'profile' | 'url';
screenName?: string;
url?: string;
}sourceType (required)
- Type:
'profile' | 'url' - Description: Type of timeline to embed
- Values:
'profile'- Display user's profile timeline (requiresscreenName)'url'- Display timeline from URL (requiresurl)
screenName (conditional)
- Type:
string - Required when:
sourceType: 'profile' - Description: X (Twitter) username without @ symbol
- Example:
'mustafaer_dev','angular','typescript'
url (conditional)
- Type:
string - Required when:
sourceType: 'url' - Description: Absolute URL of X timeline
- Examples:
'https://twitter.com/angular''https://x.com/mustafaer_dev''https://twitter.com/angular/likes''https://twitter.com/i/lists/12345'
Note:
screenNameandurlare mutually exclusive based onsourceType
Customize the timeline appearance:
interface AngularTwitterTimelineOptionsInterface {
height?: number;
width?: number;
theme?: 'light' | 'dark';
lang?: string;
}height (optional)
- Type:
number - Description: Fixed height of the timeline widget in pixels
- Range: 200-2000 (recommended)
- Default: 600
- Example:
height: 500
width (optional)
- Type:
number - Description: Fixed width of the timeline widget in pixels
- Default: Responsive (adapts to container)
- Example:
width: 400
theme (optional)
- Type:
'light' | 'dark' - Description: Color theme of the timeline
- Default:
'light' - Example:
theme: 'dark'
lang (optional)
- Type:
string - Description: Language code (BCP 47)
- Default: User's browser language
- Examples:
'en','es','fr','de','ja','pt' - Reference: BCP 47 Language Codes
⚠️ Important: X (Twitter) removed support for these parameters in November 2024
The following properties are marked as @deprecated and no longer work:
- ❌
tweetLimit- Cannot limit the number of tweets displayed - ❌
borderColor- Cannot customize border colors - ❌
chrome- Cannot toggle UI elements (noheader, nofooter, etc.) - ❌
ariaPolite- Cannot customize screen reader behavior
Migration: Remove these properties from your code. See X-TIMELINE-UPDATES.md for details.
If you're upgrading from Angular 19, the API remains compatible. Update your Angular dependencies:
ng update @angular/core @angular/cli
npm install angular-twitter-timeline@latestIf you were using deprecated parameters, update your code:
Before (No longer works):
opts = {
tweetLimit: 5, // ❌ Removed
borderColor: '#1DA1F2', // ❌ Removed
chrome: ['noheader'], // ❌ Removed
theme: 'dark',
height: 400
};After (Current):
opts = {
theme: 'dark', // ✅ Works
height: 400, // ✅ Works
width: 350, // ✅ Works (optional)
lang: 'en' // ✅ Works (optional)
};For complete migration details, see X-TIMELINE-UPDATES.md
Problem: The timeline doesn't show up
Solutions:
- Check browser console for errors
- Verify the screen name or URL is valid
- Ensure X (Twitter) widgets script loads (check Network tab)
- Check if Content Security Policy (CSP) allows Twitter scripts
<!-- Add to index.html if using CSP -->
<meta http-equiv="Content-Security-Policy"
content="script-src 'self' https://platform.twitter.com;">Problem: Type errors with sourceType
Solution: Use as const assertion for string literals:
// ✅ Correct
data = { sourceType: 'profile' as const, screenName: 'angular' };
// ❌ Wrong (Type string is not assignable to 'profile' | 'url')
data = { sourceType: 'profile', screenName: 'angular' };Problem: Timeline doesn't update when data changes
Solution: Use signals or ensure change detection:
// ✅ Using signals (recommended)
timelineData = signal({ sourceType: 'profile', screenName: 'user1' });
// Update: this.timelineData.set({ sourceType: 'profile', screenName: 'user2' });
// ✅ Using regular properties (create new object)
timelineData = { sourceType: 'profile', screenName: 'user1' };
// Update: this.timelineData = { sourceType: 'profile', screenName: 'user2' };Problem: Errors during server-side rendering
Solution: Check for window or document availability:
import { isPlatformBrowser } from '@angular/common';
import { PLATFORM_ID, inject } from '@angular/core';
export class MyComponent {
private platformId = inject(PLATFORM_ID);
ngOnInit() {
if (isPlatformBrowser(this.platformId)) {
// Timeline will render only in browser
}
}
}Contributions are welcome! Please feel free to submit a Pull Request.
# Clone the repository
git clone https://github.com/mustafaer/angular-twitter-timeline.git
cd angular-twitter-timeline
# Install dependencies
npm install
# Build the library
npm run build
# Run demo application
npm run demoFound a bug? Please open an issue with:
- Angular version
- Browser and version
- Steps to reproduce
- Expected vs actual behavior
MIT License - see LICENSE file for details
If this library helps you, consider supporting the development:
- NPM Package: https://www.npmjs.com/package/angular-twitter-timeline
- GitHub Repository: https://github.com/mustafaer/angular-twitter-timeline
- Issues & Bugs: https://github.com/mustafaer/angular-twitter-timeline/issues
- X API Updates: X-TIMELINE-UPDATES.md
| Browser | Supported |
|---|---|
| Chrome | ✅ Latest |
| Firefox | ✅ Latest |
| Safari | ✅ Latest |
| Edge | ✅ Latest |
| Opera | ✅ Latest |
Made with ❤️ by Mustafa ER