upstash / redis-js

HTTP based Redis Client for Serverless and Edge Functions
https://docs.upstash.com/redis
MIT License
671 stars 51 forks source link

Error: Unable to find environment variable: `UPSTASH_REDIS_REST_URL` | Nextjs 13 #272

Closed sagargulati closed 1 year ago

sagargulati commented 1 year ago

Greetings,

I'm on Next.js 13 created using npx create-next-app

Packages

    "@upstash/redis": "^1.18.1",
    "axios": "^1.2.1",
    "eslint": "8.29.0",
    "eslint-config-next": "13.0.6",
    "i18next": "^22.1.4",
    "mongodb": "^4.12.1",
    "next": "13.0.6",
    "next-i18next": "^13.0.0",
    "nextjs-progressbar": "^0.0.16",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-i18next": "^12.1.1",
    "react-toastify": "^9.1.1"

index.jsx

import { Fragment, useCallback, useEffect, useState } from 'react';
import { Redis } from '@upstash/redis';
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

console.log(process.env.UPSTASH_REDIS_REST_URL); // Works!!!
const redis = Redis.fromEnv(); // Error!!!

export default function Home(props) {
  const { t } = useTranslation('pages');

  const [cache, setCache] = useState('');

  useEffect(() => {
    if (process.env.NODE_ENV === 'development') {
      console.log('Upstash Cache!', JSON.stringify(cache));
    }
    if (cache === null || cache === '') {
      getCache();
    }

    return () => {
      if (process.env.NODE_ENV === 'development') {
        console.log('Upstash Cache effect!');
      }
    }
  }, [cache])

  async function getCache() {
    const member = await redis.srandmember("person");
    setCache(member);
  }

  return (
    <Fragment>
            <div className="alpha">Hello!</div>
    </Fragment>
  );
}

export async function getStaticProps({ locale }) {
  if (process.env.NODE_ENV === 'development') {
    console.log('Home page static props');
  }
  return {
    props: {
      ...(await serverSideTranslations(locale, ['global', 'pages'])),
    },
  };
}

.env.development

UPSTASH_REDIS_REST_URL="https://global-awesome-pikachu-12345.upstash.io"
UPSTASH_REDIS_REST_TOKEN="SuperAwesomeToken"

The Error

image

Tried & Failed

const redis = new Redis({
  url: process.env.UPSTASH_REDIS_REST_URL,
  token: process.env.UPSTASH_REDIS_REST_TOKEN,
});

Seems to work with passed as STATIC!

const redis = new Redis({
    url: 'https://global-awesome-pikachu-12345.upstash.io',
    token: '********',
});

Even though I have UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN in my .env.development file. I also tried to rename the file to .env and I still get the same error.

If I use the code console.log(process.env.UPSTASH_REDIS_REST_URL), it does fetch the value and shows them in the console.

Can you suggest what could be wrong?

Thanks!

chronark commented 1 year ago

Actually you are using the old pages directory. You can't just use it like this. Only environment variables prefixed with NEXT_PUBLIC_ are going to be exposed.

You need to either use the app dir or one of the old ways of data fetching like getServersideProps

We have an example for the appdir here which worked fine: https://docs.upstash.com/redis/quickstarts/nextjs13

sagargulati commented 1 year ago

Even though I have UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN in my .env.development file. I also tried to rename the file to .env and I still get the same error.

If I use the code console.log(process.env.UPSTASH_REDIS_REST_URL), it does fetch the value and shows them in the console.

Also, NEXT_PUBLIC usually exposes the data publically and shows tokens and keys to the people, which we usually don't want!

We use /pages/ directory, and we also tried /src/pages. Any suggestion we can make it work without the apps directory?

Thanks!

chronark commented 1 year ago

Yes as I mentioned above, please use either getServersideProps, getStaticPropsorgetInitialProps` to load the data. you can not use the Redis client in the frontend without exposing the token