> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Angular Web SDK setup
> Integrate OneSignal Web Push Notifications into your Angular application using the onesignal-ngx package. Learn how to install, configure, and troubleshoot service workers to deliver seamless push notifications.
export const SdkReleasesIframe = ({sdkFilter = undefined, viewMode = undefined, height, ...frameProps}) => {
const baseUrl = 'https://onesignal.github.io/sdk-releases';
const buildUrl = (theme, sdkFilter, viewMode) => {
const url = new URL(baseUrl);
const params = new URLSearchParams();
if (theme) {
params.set('theme', theme);
}
if (sdkFilter) {
params.set('sdk', sdkFilter);
}
if (viewMode) {
params.set('viewMode', viewMode);
}
if (params.toString()) {
url.search = params.toString();
}
return url.toString();
};
const detectTheme = () => {
if (document.documentElement.classList.contains('dark')) {
return 'dark';
}
return 'light';
};
const [theme, setTheme] = useState('light');
const [iframeSrc, setIframeSrc] = useState(() => {
const initialTheme = detectTheme();
return buildUrl(initialTheme, sdkFilter, viewMode);
});
useEffect(() => {
const currentTheme = detectTheme();
setTheme(currentTheme);
setIframeSrc(buildUrl(currentTheme, sdkFilter, viewMode));
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleThemeChange = () => {
const newTheme = detectTheme();
setTheme(newTheme);
setIframeSrc(buildUrl(newTheme, sdkFilter, viewMode));
};
if (mediaQuery.addEventListener) {
mediaQuery.addEventListener('change', handleThemeChange);
} else {
mediaQuery.addListener(handleThemeChange);
}
window.addEventListener('storage', handleThemeChange);
const observer = new MutationObserver(handleThemeChange);
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'data-theme']
});
return () => {
if (mediaQuery.removeEventListener) {
mediaQuery.removeEventListener('change', handleThemeChange);
} else {
mediaQuery.removeListener(handleThemeChange);
}
window.removeEventListener('storage', handleThemeChange);
observer.disconnect();
};
}, [sdkFilter, viewMode]);
const getIframeHeight = () => {
if (viewMode === 'table') {
return '450';
}
if (viewMode === 'mini') {
return '170';
}
return '800';
};
const iframeHeight = height || getIframeHeight();
return