Astro 中的 React 组件无法工作,无法访问环境变量

问题描述 投票:0回答:1

我最近开始使用 Astro,对如何在框架内正确使用 React 组件感到有点困惑。我确信我的错误可能是一个愚蠢的错误,我不是专业的开发人员,这对我来说都是新的。

我的导航栏不起作用。当我单击移动菜单按钮时,没有任何反应,并且在页面加载时,我收到以下错误:

[Error] [astro-island] Error hydrating /src/components/Navbar.tsx Error: Missing Supabase URL or anon key Module Code — supabase.ts:7 (anonymous function) (localhost:1171:3738) 

这是我的导航栏组件:

import { useState, useEffect } from "react";
import { Menu, X, User, LogOut } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { supabase } from "@/lib/supabase";

export const Navbar = () => {
  const [open, setOpen] = useState(false);
  const [loggedIn, setLoggedIn] = useState(false);

  const checkUser = async () => {
    const session = await supabase.auth.getSession();
    if (session) {
      setLoggedIn(true);
    } else {
      setLoggedIn(false);
    }
  };

  checkUser();

  return (
    <nav className="bg-white border-b sticky top-0">
      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
        <div className="relative flex items-center justify-between h-16">
          <div className="flex-1 flex items-center justify-start sm:items-stretch sm:justify-start">
            <div className="flex-shrink-0">
              <a href="/">
                <img className="h-8 w-auto" src="/favicon.svg" alt="Workflow" />
              </a>
            </div>
            <div className="hidden sm:block sm:ml-6">
              <div className="flex space-x-2">
                <a
                  href="#"
                  className="text-gray-900 hover:text-gray-500 hover:text-white px-3 py-2 text-sm"
                >
                  Stories
                </a>
                <a
                  href="#"
                  className="text-gray-900 hover:text-gray-500 hover:text-white px-3 py-2 text-sm"
                >
                  Writers
                </a>
                <a
                  href="#"
                  className="text-gray-900 hover:text-gray-500 hover:text-white px-3 py-2 text-sm"
                >
                  Blog
                </a>
                <a
                  href="#"
                  className="text-gray-900 hover:text-gray-500 hover:text-white px-3 py-2 text-sm"
                >
                  About
                </a>
              </div>
            </div>
          </div>
          <div className="flex items-center space-x-2">
            {!loggedIn && (
              <>
                <Button className="hidden sm:inline-block" variant="outline">
                  Login
                </Button>
                <Button className="hidden sm:inline-block">Sign Up</Button>
              </>
            )}
            {loggedIn && (
              <DropdownMenu>
                <DropdownMenuTrigger>
                  <Avatar className="h-8 w-8">
                    <AvatarImage src="https://github.com/shadcn.png" />
                    <AvatarFallback>CN</AvatarFallback>
                  </Avatar>
                </DropdownMenuTrigger>
                <DropdownMenuContent>
                  <a href="/profile">
                    <DropdownMenuItem>
                      <User />
                      My Profile
                    </DropdownMenuItem>
                  </a>
                  <DropdownMenuItem>
                    <LogOut />
                    Log out
                  </DropdownMenuItem>
                </DropdownMenuContent>
              </DropdownMenu>
            )}
            <div className="sm:hidden">
              <button
                type="button"
                className="inline-flex items-center justify-center text-gray-500 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white"
                aria-controls="mobile-menu"
                aria-expanded={open ? "true" : "false"}
                onClick={() => setOpen(!open)}
              >
                <span className="sr-only">Open main menu</span>
                {open ? (
                  <X className="block h-6 w-6" aria-hidden="true" />
                ) : (
                  <Menu className="block h-6 w-6" aria-hidden="true" />
                )}
              </button>
            </div>
          </div>
        </div>
      </div>

      <div
        className={`sm:hidden ${open ? "block" : "hidden"}`}
        id="mobile-menu"
      >
        <div className="px-2 pt-2 pb-3 space-y-1">
          <a
            href="#"
            className="text-gray-900 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium"
          >
            Dashboard
          </a>
          <a
            href="#"
            className="text-gray-900 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium"
          >
            Team
          </a>
          <a
            href="#"
            className="text-gray-900 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium"
          >
            Projects
          </a>
          <a
            href="#"
            className="text-gray-900 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium"
          >
            Calendar
          </a>
          <div className="mt-4 space-y-1">
            <Button className="w-full" variant="outline">
              Login
            </Button>
            <Button className="w-full">Sign Up</Button>
          </div>
        </div>
      </div>
    </nav>
  );
};

我的 .env 文件已正确设置,我的 .lib/supabase.ts 文件如下:

import { createClient } from "@supabase/supabase-js";

const supabaseUrl = import.meta.env.SUPABASE_URL;
const supabaseAnonKey = import.meta.env.SUPABASE_ANON_KEY;

if (!supabaseUrl || !supabaseAnonKey) {
  throw new Error("Missing Supabase URL or anon key");
}

export const supabase = createClient(supabaseUrl, supabaseAnonKey);

我真的很感激这里的任何指点。

reactjs supabase astrojs supabase-js
1个回答
0
投票

来自 Astro:使用环境变量

请注意,虽然所有环境变量都可在服务器端代码中使用,但出于安全目的,只有前缀为

PUBLIC_
的环境变量可在客户端代码中使用。

所以应该是:

const supabaseUrl = import.meta.env.PUBLIC_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.PUBLIC_SUPABASE_ANON_KEY;

是的,这两个是可以安全地暴露在客户端,假设:

您已启用行级安全性。

© www.soinside.com 2019 - 2024. All rights reserved.