contentful / live-preview

Preview SDK for both the field tagging connection + live content updates
https://www.contentful.com/developers/docs/tutorials/general/live-preview/
MIT License
64 stars 14 forks source link

Compatibility with Angular app #923

Closed guillermodelagala closed 2 weeks ago

guillermodelagala commented 2 weeks ago

Describe the bug Steps to have Contentful Live Preview working with Angular app.

Expected behavior Having Angular apps working with Contentful Live Preview.

Additional context Please, provide the steps to have it working. It's going to be useful for customers.

YvesRijckaert commented 2 weeks ago

Hi! Some users have successfully set up live preview for Angular by looking at the vanilla-js example.

To give you some inspiration, this is small POC we did a while ago. It doesn’t include the SDK, but just more a generic solution on how you could approach it:

app.component.ts

import { Component } from '@angular/core';
import { PostMessageService } from './post-message.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-root',
  template: `
    <div class="content" role="main">{{ data }}</div>
    <router-outlet></router-outlet>
  `,
})
export class AppComponent {
  data: string = '';
  private subscription: Subscription | null = null;

  constructor(private postMessageService: PostMessageService) {}

  ngOnInit() {
    this.subscription = this.postMessageService.data$.subscribe(
      (data: string) => {
        this.data = data;
      }
    );
  }

  ngOnDestroy() {
    this.subscription?.unsubscribe();
  }
}

post-message.service.ts

import { Injectable, OnDestroy } from '@angular/core';
import { Observable, Subject } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class PostMessageService implements OnDestroy {
  private dataSubject: Subject<string> = new Subject<string>();
  public data$: Observable<string> = this.dataSubject.asObservable();

  constructor() {
    window.addEventListener('message', this.handlePostMessage.bind(this));
  }

  ngOnDestroy(): void {
    window.removeEventListener('message', this.handlePostMessage);
  }

  handlePostMessage(event: MessageEvent<string>) {
    this.dataSubject.next(event.data ?? '');
  }
}