Integrating MeshBase with Angular
Build enterprise-grade Angular applications powered by MeshBase. Services, RxJS, HttpClient, and Angular Universal—all covered.
Why MeshBase + Angular?
🏢Enterprise Ready
Angular + MeshBase = enterprise-grade content management. TypeScript-first, testable, scalable architecture.
🔄RxJS Integration
MeshBase API calls return Observables. Perfect for Angular's reactive patterns and async pipes.
🎯Type Safety
Full TypeScript support with interfaces and models. Catch errors at compile time, not runtime.
🚀Angular Universal
Server-side rendering with Angular Universal works seamlessly with MeshBase for SEO and performance.
What You'll Need
- ✓Angular 15+ project
- ✓A MeshBase account with content types defined
- ✓Your MeshBase public API key
Quick Start
Set up MeshBase in your Angular app with a service.
1. Configure environment
Update src/environments/environment.ts:
export const environment = {
production: false,
meshbase: {
apiUrl: 'https://api.meshbase.io/v1',
apiKey: 'your-api-key-here'
}
};2. Define models
Create src/app/models/blog-post.model.ts:
export interface BlogPost {
id: string;
title: string;
excerpt: string;
content: string;
coverImage?: string;
publishedAt: string;
}
export interface MeshBaseResponse<T> {
data: T[];
meta?: {
total: number;
page: number;
};
}3. Create content service
Generate and update src/app/services/content.service.ts:
ng generate service services/contentimport { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { environment } from '../../environments/environment';
import { BlogPost, MeshBaseResponse } from '../models/blog-post.model';
@Injectable({
providedIn: 'root'
})
export class ContentService {
private apiUrl = environment.meshbase.apiUrl;
private apiKey = environment.meshbase.apiKey;
private get headers(): HttpHeaders {
return new HttpHeaders({
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
});
}
constructor(private http: HttpClient) {}
getBlogPosts(): Observable<BlogPost[]> {
return this.http.get<MeshBaseResponse<BlogPost>>(
`${this.apiUrl}/blog-posts`,
{ headers: this.headers }
).pipe(
map(response => response.data)
);
}
getBlogPost(id: string): Observable<BlogPost> {
return this.http.get<BlogPost>(
`${this.apiUrl}/blog-posts/${id}`,
{ headers: this.headers }
);
}
}4. Use in components
Create src/app/blog/blog-list.component.ts:
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { ContentService } from '../services/content.service';
import { BlogPost } from '../models/blog-post.model';
@Component({
selector: 'app-blog-list',
template: `
<div class="blog-list">
<h1>Blog Posts</h1>
<div *ngIf="posts$ | async as posts; else loading">
<article *ngFor="let post of posts">
<h2>
<a [routerLink]="['/blog', post.id]">
{{ post.title }}
</a>
</h2>
<p>{{ post.excerpt }}</p>
</article>
</div>
<ng-template #loading>
<p>Loading posts...</p>
</ng-template>
</div>
`
})
export class BlogListComponent implements OnInit {
posts$!: Observable<BlogPost[]>;
constructor(private contentService: ContentService) {}
ngOnInit(): void {
this.posts$ = this.contentService.getBlogPosts();
}
}You're Done!
Your Angular app now fetches MeshBase content. The async pipe handles subscriptions automatically—clean and reactive!
State Management with NgRx
For complex apps, integrate MeshBase with NgRx.
Install NgRx
ng add @ngrx/store @ngrx/effectsCreate actions
// store/blog/blog.actions.ts
import { createAction, props } from '@ngrx/store';
import { BlogPost } from '../../models/blog-post.model';
export const loadPosts = createAction('[Blog] Load Posts');
export const loadPostsSuccess = createAction(
'[Blog] Load Posts Success',
props<{ posts: BlogPost[] }>()
);
export const loadPostsFailure = createAction(
'[Blog] Load Posts Failure',
props<{ error: string }>()
);Create effects
// store/blog/blog.effects.ts
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { of } from 'rxjs';
import { map, catchError, switchMap } from 'rxjs/operators';
import { ContentService } from '../../services/content.service';
import * as BlogActions from './blog.actions';
@Injectable()
export class BlogEffects {
loadPosts$ = createEffect(() =>
this.actions$.pipe(
ofType(BlogActions.loadPosts),
switchMap(() =>
this.contentService.getBlogPosts().pipe(
map(posts => BlogActions.loadPostsSuccess({ posts })),
catchError(error => of(BlogActions.loadPostsFailure({ error: error.message })))
)
)
)
);
constructor(
private actions$: Actions,
private contentService: ContentService
) {}
}Server-Side Rendering (Angular Universal)
Pre-render pages with Angular Universal for better SEO and initial load performance.
Add Angular Universal
ng add @nguniversal/express-engineTransfer state
Avoid fetching data twice (server + client):
import { TransferState, makeStateKey } from '@angular/platform-browser';
const POSTS_KEY = makeStateKey<BlogPost[]>('posts');
@Injectable({ providedIn: 'root' })
export class ContentService {
constructor(
private http: HttpClient,
private transferState: TransferState
) {}
getBlogPosts(): Observable<BlogPost[]> {
// Try to get from transfer state first
const cachedPosts = this.transferState.get(POSTS_KEY, null);
if (cachedPosts) {
this.transferState.remove(POSTS_KEY);
return of(cachedPosts);
}
// Fetch from API
return this.http.get<MeshBaseResponse<BlogPost>>(
`${this.apiUrl}/blog-posts`,
{ headers: this.headers }
).pipe(
map(response => response.data),
tap(posts => this.transferState.set(POSTS_KEY, posts))
);
}
}HTTP Interceptors
Add authentication headers globally with an interceptor.
Create interceptor
// interceptors/meshbase.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';
import { environment } from '../../environments/environment';
@Injectable()
export class MeshbaseInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) {
// Only add auth to MeshBase requests
if (req.url.includes(environment.meshbase.apiUrl)) {
const authReq = req.clone({
setHeaders: {
Authorization: `Bearer ${environment.meshbase.apiKey}`
}
});
return next.handle(authReq);
}
return next.handle(req);
}
}Register in app module
// app.module.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { MeshbaseInterceptor } from './interceptors/meshbase.interceptor';
@NgModule({
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MeshbaseInterceptor,
multi: true
}
]
})Cleaner Service Code
With interceptors, your service doesn't need to handle auth headers manually. Cleaner code, centralized authentication!
Next Steps
- →Handle images and media
Upload and serve media files
- →Explore the full API
Filtering, sorting, pagination, and more
- →Angular Documentation
Learn more about Angular