@types/youtube, reference error:YT is not defined

i’m trying to use typescript in sveltekit to implement a youtube API. I’m using @types/youtube, hoping that I can get better results getting the video to work by passing the URL and get videoDuration. but so far it’s not working.

i was following the template of youtube API, I could get js and videoID version to work but somehow i was having trouble with typescript and passing URL

Any help or experience is appreciated.

<!-- to do: 
 1) need to handle youtube shorts by replacing short with watch?v= 
 2) chatbot window on same screen like windows explorer or new page, take some time to reflect 
 -->
<script lang="ts">
    // page function from default app/stores library enables script to get url searchparams from
    // url 
    import { page } from '$app/stores';
    import { onMount, onDestroy } from 'svelte';
    

    let subtitles: {id: string, start: number; end: number; text: string} [] = [];
    let videoUrl: string = '';
    let duration: number = 0;
    let currentTime: number = 0;

    let player = new YT.Player("id",{
        events: {
          onReady(event: YT.PlayerEvent) {
            const targetPlayer: YT.Player = event.target;
          },
          onStateChange(event: YT.OnStateChangeEvent) {
            const targetPlayer: YT.Player = event.target;
            const playerData: YT.PlayerState = event.data;
          }
        }
    });

      

    // function to fetch subtitles from cache, database or AI server.
    async function fetchSubtitles() {
      subtitles = [
      { id: "1", start: 0, end: 5, text: "Hello, welcome to our video." },
      { id: "2", start: 6, end: 10, text: "Today, we'll discuss Svelte components." },
      { id: "3", start: 11, end: 15, text: "Let's dive right in!" },
      { id: "4", start: 16, end: 20, text: "Svelte makes building UIs a breeze." },
      ];
    }

    /*****************  onMount() ******************/
    onMount(() => {
      // I believe that page should be a reactive var, so query is renewed every time 
      // url changes. But on the other hand, since all vars are reactive, 
      const query = $page.url.searchParams;
      const encodedUrl = query.get('videoUrl') || '';
      
      //const tag: HTMLScriptElement = document.createElement('script'); 
      
      // Decode the URL before processing it
      videoUrl = decodeURIComponent(encodedUrl);

      // Load the YouTube iframe API script dynamically
      const tag = document.createElement('script');
      tag.src = 'https://www.youtube.com/iframe_api';
      document.body.appendChild(tag);

      // Define a global callback that YouTube API will call once it's ready
      (window as any).onYouTubeIframeAPIReady = () => {
        player = new YT.Player("id",{
          events: {
            onReady(event: YT.PlayerEvent) {
              const targetPlayer: YT.Player = event.target;
            },
            onStateChange(event: YT.OnStateChangeEvent) {
              const targetPlayer: YT.Player = event.target;
              const playerData: YT.PlayerState = event.data;
            }
          }
        })
         };
  
      // Ensure that the URL is a valid YouTube URL
      if (videoUrl && !videoUrl.includes("youtube.com") && !videoUrl.includes("youtu.be")) {
        videoUrl = ''; // Reset if not a valid YouTube URL
      }
      
        //insert iframe api onto DOM
        //tag.src = "https://www.youtube.com/iframe_api";
        //document.body.appendChild(tag);

      fetchSubtitles();
    });
    /************* OnMount ****************/

    // call eventlistener function when onReady event fire is received by API.
    player.addEventListener("onReady", 
      (event: YT.PlayerEvent) => {
        duration = player.getDuration();
        currentTime = player.getCurrentTime();
        });
   /****
    // called when the player is ready
    function onPlayerReady(event): void {
        duration = player.getDuration();

        setInterval((): void => {
          currentTime = YT.getCurrentTime();
        }, 1000);
      }
    ***/
    //$: duration = player ? player.getDuration() : 0;

    // Function to construct YouTube URL into embedded form
    function getEmbedUrl(url: string): string {
      if (!url) return '';
  
      // Handle short links like youtu.be/xyz
      const shortLinkMatch = url.match(/youtu.be/([^?]+)/);
      if (shortLinkMatch) {
        return `https://www.youtube.com/embed/${shortLinkMatch[1]}`;
      }
  
      // Handle regular YouTube links like youtube.com/watch?v=xyz
      const regularLinkMatch = url.match(/v=([^&]+)/);
      if (regularLinkMatch) {
        return `https://www.youtube.com/embed/${regularLinkMatch[1]}`;
      }
  
      return '';
    }


  </script>
  
  <main>
    <h1>Watch Video</h1>
  
    {#if videoUrl}
      <div id="id"></div>

      <p> Duration: {duration} seconds </p>
      <p> Current Time: {currentTime} seconds </p>
    {:else}
      <p>No valid video URL provided. Please check the link and try again.</p>
    {/if}

    

  </main>
  
  <style>
    main {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 2rem;
    }
  
    iframe {
      margin-top: 1rem;
    }
  </style>
  

  <!-- 
    Watch.svelte page is a parent component to subtitleEditor.svelte component in library.
    Primary function is to embed youtube video for display, based on the URL that user 
    submitted in the (tentative) main page.svelte 
    
    apparently it is better to have subtitles fetched from parent component. 
    Then passed assign value to props of SubtitleEditor component.
  
  -->

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật