diff --git a/.eslintrc.json b/.eslintrc.json index 6699e02..f9406b5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -10,6 +10,7 @@ "object-curly-newline": "off", "react/require-default-props": "off", "implicit-arrow-linebreak": "off", - "function-paren-newline": "off" + "function-paren-newline": "off", + "@typescript-eslint/indent": "off" } } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 86de46b..40012da 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -4,11 +4,12 @@ import { Inter } from 'next/font/google'; import { Analytics } from '@vercel/analytics/react'; import { SpeedInsights } from '@vercel/speed-insights/next'; import Provider from '@/providers'; -import './globals.css'; import Header from '@/components/header'; import Footer from '@/components/footer'; +import ChannelTalk from '@/components/channel-talk'; import Favicon from '../../public/favicon.ico'; import AppleTouch from '../../public/apple-touch-icon.png'; +import './globals.css'; const inter = Inter({ subsets: ['latin'] }); @@ -56,6 +57,7 @@ export default function RootLayout({ children }: Props) { + ); diff --git a/src/components/channel-talk/index.tsx b/src/components/channel-talk/index.tsx new file mode 100644 index 0000000..14e674b --- /dev/null +++ b/src/components/channel-talk/index.tsx @@ -0,0 +1,64 @@ +'use client'; + +import Script from 'next/script'; +import { useEffect } from 'react'; +import * as Env from '@/utils/env'; + +export default function ChannelTalk() { + const pluginKey = Env.get({ key: 'CHANNEL_TALK_PLUGIN_KEY' }); + + useEffect(() => { + try { + const { ChannelIO } = window; + + if (ChannelIO) { + ChannelIO('boot', { + pluginKey, + }); + } + } catch (error) { + console.error('ChannelIO is not defined'); + } + }, [pluginKey]); + + return ( + + ); +} diff --git a/src/types/window.d.ts b/src/types/window.d.ts new file mode 100644 index 0000000..402797f --- /dev/null +++ b/src/types/window.d.ts @@ -0,0 +1,15 @@ +interface BootOptions { + pluginKey: string; +} + +type ChannelIO = ( + command: 'boot', + bootOption: BootOptions, + callback?: () => void, +) => void; + +export declare global { + interface Window { + ChannelIO?: ChannelIO; + } +} diff --git a/src/utils/env.ts b/src/utils/env.ts index 405ac48..810fb93 100644 --- a/src/utils/env.ts +++ b/src/utils/env.ts @@ -7,7 +7,11 @@ function makeOption(value: string | undefined | null): O.Option { } interface Get { - key: 'SUPABASE_URL' | 'SUPABASE_ANON_KEY' | 'BASE_URL'; + key: + | 'SUPABASE_URL' + | 'SUPABASE_ANON_KEY' + | 'BASE_URL' + | 'CHANNEL_TALK_PLUGIN_KEY'; } export function get({ key }: Get) { @@ -16,6 +20,10 @@ export function get({ key }: Get) { .with('SUPABASE_URL', () => process.env.SUPABASE_URL) .with('SUPABASE_ANON_KEY', () => process.env.SUPABASE_ANON_KEY) .with('BASE_URL', () => process.env.BASE_URL) + .with( + 'CHANNEL_TALK_PLUGIN_KEY', + () => process.env.NEXT_PUBLIC_CHANNEL_TALK_PLUGIN_KEY, + ) .exhaustive(), makeOption, );