flowbite icon indicating copy to clipboard operation
flowbite copied to clipboard

Angular 19 SSR

Open erwinagpasa opened this issue 8 months ago • 2 comments

Describe the bug Flowbite isn't initialized immediately after saving app.component.html, and a browser reload is required for it to work.

To Reproduce Steps to reproduce the behavior:

  1. Clone https://github.com/erwinagpasa/ngdashboard
  2. Edit app.component.html
  3. Then save

Expected behavior Flowbite should initialize automatically, and the modal should work without needing to reload the browser.

//! app/services/flowbite.service.ts

import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

@Injectable({
  providedIn: 'root'
})
export class FlowbiteService {
  constructor(@Inject(PLATFORM_ID) private platformId: any) { }

  loadFlowbite(callback: (flowbite: any) => void) {
    if (isPlatformBrowser(this.platformId)) {
      import('flowbite').then(flowbite => {
        callback(flowbite);
      });
    }
  }
}
//! /Users/developer/angular-project/ngdashboard/src/app/app.component.ts

import { Component, OnInit } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { FlowbiteService } from './services/flowbite.service';
import { initFlowbite } from 'flowbite';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent implements OnInit {
  title = 'ngdashboard';

  constructor(private flowbiteService: FlowbiteService) { }

  ngOnInit(): void {
    this.flowbiteService.loadFlowbite((flowbite) => {
      initFlowbite();
    });
  }

}

/Users/developer/angular-project/ngdashboard/src/styles.css

@import "tailwindcss";
@import "flowbite/src/themes/default";
/* @plugin "flowbite/plugin"; */
@source "../node_modules/flowbite";

erwinagpasa avatar Mar 21 '25 07:03 erwinagpasa

I am running into the same issue. Anytime I hot reload, the JS interactivity goes aways.

hnatowbk avatar Jun 06 '25 13:06 hnatowbk

Same problem here. I've implemented a small workaround that solves this until a proper fix.:

import { Component, isDevMode, OnInit } from '@angular/core';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { initFlowbite } from 'flowbite';
import { debounceTime, Subject, tap } from 'rxjs';

@Component({
  imports: [RouterModule, TranslateModule],
  selector: 'app-root',
  standalone: true,
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss',
})
export class AppComponent implements OnInit {
  ngOnInit(): void {
    initFlowbite();
    this.flowbiteLiveReload();
  }

  private flowbiteLiveReload() {
    //only do this in dev mode
    if (isDevMode()) {
      //create a trottle observable to avoid too many calls
      const observer$ = new Subject<void>();
      observer$
        .pipe(
          debounceTime(100),
          tap(() => {
            initFlowbite();
          })
        )
        .subscribe();

      const observer = new MutationObserver(() => {
        observer$.next();
      });

      //change 'app-root' to the root element of your app
      observer.observe(document.querySelector('app-root') as HTMLElement, {
        childList: true, //Child list changes on live-reload
      });
    }
  }
}

murilogoedert avatar Jun 13 '25 17:06 murilogoedert