Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

environment variables still are not available on Cloudflare Pages SSR #6130

Closed
1 task
excelsior091224 opened this issue Feb 4, 2023 · 15 comments
Closed
1 task

Comments

@excelsior091224
Copy link

excelsior091224 commented Feb 4, 2023

What version of astro are you using?

2.0.6

Are you using an SSR adapter? If so, which one?

Cloudflare

What package manager are you using?

npm

What operating system are you using?

Linux(Raspberry Pi OS)

Describe the Bug

In my blog, I'm using microCMS with this tutorial.
In this method, the environment variables MICROCMS_SERVICE_DOMAIN and MICROCMS_API_KEY are read in src/library/microcms.ts and used to call the API to receive blog posts.
src/library/microcms.ts

import { createClient, MicroCMSQueries } from "microcms-js-sdk";
const client = createClient({
  serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
  apiKey: import.meta.env.MICROCMS_API_KEY,
});

//型定義
export type Blog = {
  id: string;
  createdAt: string;
  updatedAt: string;
  publishedAt: string;
  revisedAt: string;
  title: string;
  content: string;
};
export type BlogResponse = {
  totalCount: number;
  offset: number;
  limit: number;
  contents: Blog[];
};

//APIの呼び出し
export const getBlogs = async (queries?: MicroCMSQueries) => {
  return await client.get<BlogResponse>({ endpoint: "blogs", queries });
};
export const getBlogDetail = async (
  contentId: string,
  queries?: MicroCMSQueries
) => {
  return await client.getListDetail<Blog>({
    endpoint: "blogs",
    contentId,
    queries,
  });
};

Since .env is not available for deployment with Cloudflare Pages, these environment variables are set from the Cloudflare Pages configuration.
However, when deploying in SSR mode using the Cloudflare adapter, the following error occurs at the end of the deployment and it ends in failure.

21:41:54.066 | Deploying your site to Cloudflare's global network...
-- | --
21:41:56.950 | Uploading... (12/12)
21:41:56.951 |  
21:41:56.954 | ✨ Success! Uploaded 0 files (12 already uploaded) (0.56 sec)
21:41:56.954 |  
21:41:57.383 | ✨ Upload complete!
21:41:58.622 | Success: Assets published!
21:41:59.230 | Error: Failed to publish your Function. Got error: Uncaught Error: parameter is required (check serviceDomain and apiKey)   at worker.mjs:83:3411 in Tc   at worker.mjs:436:480

It is clear that the environment variables are not readable, since you say that there is no serviceDomain and apiKey.
The issue is closed in #5301 as being resolved, but it is not resolved by any stretch of the imagination.
#5234 says to define it in vite.define in the following way.

vite: {
    define: {
      "process.env.SECRET": process.env.SECRET,
    }
}

In fact, this worked. However, shouldn't the documentation then say "To use environment variables in SSR mode, they must be defined in vite.define"?
Otherwise, it should be modified to work the normal way (import.meta.env).

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-vnbnoz?file=README.md&on=stackblitzhttps://stackblitz.com/edit/github-vnbnoz?file=README.md&on=stackblitz

Participation

  • I am willing to submit a pull request for this issue.
@excelsior091224 excelsior091224 changed the title environment variables still are not available on Cloudflare Pages environment variables still are not available on Cloudflare Pages SSR Feb 4, 2023
@AirBorne04
Copy link
Contributor

AirBorne04 commented Feb 4, 2023

Hi,

I understand it is a little confusing, and we would like to change this behavior, but unfortunately we can't.
On Cloudflare the env vars are passed to the request and cant be accessed before the first request. Therefore they are undefinded in you example, this limitation is mentioned also in the docs

@AirBorne04 AirBorne04 closed this as not planned Won't fix, can't repro, duplicate, stale Feb 4, 2023
@excelsior091224
Copy link
Author

Hi,

I understand it is a little confusing, and we would like to change this behavior, but unfortunately we can't. On Cloudflare the env vars are passed to the request and cant be accessed before the first request. Therefore they are undefinded in you example, this limitation is mentioned also in the docs

So, does that mean I have to call import.meta.env every time?
What nonsense.

@AirBorne04
Copy link
Contributor

You do not need to call it every time, but you might need to create a factory function and store the client instance.
Cloudflare env vars work like this, nothing we can do about that.
If I remember correctly it should be an option to access the env vars at cloudflares build time and use the vite define option to embed them instead of accessing them through the request.

@excelsior091224
Copy link
Author

You do not need to call it every time, but you might need to create a factory function and store the client instance. Cloudflare env vars work like this, nothing we can do about that. If I remember correctly it should be an option to access the env vars at cloudflares build time and use the vite define option to embed them instead of accessing them through the request.

I created a factory function clientFactoryFunction in /src/library/microcms.ts, and changed to use const client = createClient( clientFactoryFunction()); in getBlogs and getBlogDetail, but still failed to deploy in SSR mode.
https://github.com/excelsior091224/astro_test/runs/11113808483

09:48:36.942 | Deploying your site to Cloudflare's global network...
-- | --
09:48:40.516 | Uploading... (12/12)
09:48:40.518 |  
09:48:40.520 | ✨ Success! Uploaded 0 files (12 already uploaded) (1.34 sec)
09:48:40.521 |  
09:48:40.771 | ✨ Upload complete!
09:48:42.173 | Success: Assets published!
09:48:42.818 | Error: Failed to publish your Function. Got error: Uncaught Error: parameter is required (check serviceDomain and apiKey)   at worker.mjs:83:3411 in kr   at worker.mjs:436:477

How can I get it to function properly?
https://github.com/excelsior091224/astro_test/blob/master/src/library/microcms.ts

export const clientFactoryFunction = () => {
  return {
    serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
    apiKey: import.meta.env.MICROCMS_API_KEY,
  }
}
export const getBlogs = async (queries?: MicroCMSQueries) => {
  const client = createClient(clientFactoryFunction());
  const data = await client.get<BlogResponse>({ endpoint: "blogs", queries });

  if (data.offset + data.limit < data.totalCount) {
    queries ? (queries.offset = data.offset + data.limit) : "";
    const result: BlogResponse = await getBlogs(queries);
    return {
      offset: result.offset,
      limit: result.limit,
      contents: [...data.contents, ...result.contents],
      totalCount: result.totalCount,
    };
  }
  return data;
};

export const getBlogDetail = async (
  contentId: string,
  queries?: MicroCMSQueries
) => {
  const client = createClient(clientFactoryFunction());
  return await client.getListDetail<Blog>({
    endpoint: "blogs",
    contentId,
    queries,
  });
};

@AirBorne04
Copy link
Contributor

AirBorne04 commented Feb 5, 2023

Hi I think you only need to remove this line.
The issue is that when on deployment you already get this error you are doing something wrong 😄 that is due to the fact that you access the import.meta.env before a request was made.

const clientFactoryFunction = () => {
return createClient({
  serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
  apiKey: import.meta.env.MICROCMS_API_KEY,
});

and than only use it from a function like

export const getBlogDetail = async (
  contentId: string,
  queries?: MicroCMSQueries
) => {
  const client = clientFactoryFunction();
  return await client.getListDetail<Blog>({
    endpoint: "blogs",
    contentId,
    queries,
  });
};

In case you want to cache the client instance you might want to change your factory function to something like this:

let _clientInst = null;
const clientFactoryFunction = () => {
  if (!_clientInst) {
    _clientInst = createClient({
      serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
      apiKey: import.meta.env.MICROCMS_API_KEY
    });
  }
  return _clientInst;
};

@excelsior091224
Copy link
Author

Thanks for advice, but it didn't work well.
https://github.com/excelsior091224/astro_test/blob/ec388d9cb34671174308fcf9557b43d78b945efd/src/library/microcms.ts
With this code, deploy is looks works.

20:30:47.657 | Deploying your site to Cloudflare's global network...
-- | --
20:30:50.538 | Uploading... (12/12)
20:30:50.538 |  
20:30:50.542 | ✨ Success! Uploaded 0 files (12 already uploaded) (0.35 sec)
20:30:50.542 |  
20:30:50.800 | ✨ Upload complete!
20:30:52.082 | Success: Assets published!
20:30:54.059 | Success: Your site was deployed!

But, accessing these pages which using getBlogs and getBlogDetail, pages displays HTTP ERROR 500.
https://1a7a4f5a.astro-test-b4j.pages.dev/blog
code
https://github.com/excelsior091224/astro_test/blob/master/src/pages/blog.astro
https://github.com/excelsior091224/astro_test/blob/master/src/pages/blog/%5BblogId%5D.astro
I have no way to see the error logs.

@AirBorne04
Copy link
Contributor

AirBorne04 commented Feb 5, 2023

Hey, I know error logging is a bit tricky on cloudflare pages can you try anything suggested here?
I would try wrangler local first.

@excelsior091224
Copy link
Author

dev in wrangler npx wrangler pages dev --proxy 5000 --binding MICROCMS_SERVICE_DOMAIN="xxxxxxxxxxxxxx" MICROCMS_API_KEY="xxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -- npm run dev -- --host --port 5000 command, but no 500 error occurred in this environment.
However, when I deploy, I get a 500 error.

@AirBorne04
Copy link
Contributor

AirBorne04 commented Feb 5, 2023

Can you put a try catch on your function and return the error? Or just add a route returning the envs?

@excelsior091224
Copy link
Author

I was able to reproduce the error after renaming .env.

Error
An error occurred.
parameter is required (check serviceDomain and apiKey)
cjs/microcms-js-sdk.js:1:2411
Open in editor
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("qs"),t=require("cross-fetch");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=n(e),o=n(t),i=function(){return(i=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function c(e,t,n,r){return new(n||(n=Promise))((function(o,i){function c(e){try{s(r.next(e))}catch(e){i(e)}}function u(e){try{s(r.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(c,u)}s((r=r.apply(e,t||[])).next())}))}function u(e,t){var n,r,o,i,c={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;i&&(i=0,u[0]&&(c=0)),c;)try{if(n=1,r&&(o=2&u[0]?r.return:u[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,u[1])).done)return o;switch(r=0,o&&(u=[2&u[0],o.value]),u[0]){case 0:case 1:o=u;break;case 4:return c.label++,{value:u[1],done:!1};case 5:c.label++,r=u[1],u=[0];continue;case 7:u=c.ops.pop(),c.trys.pop();continue;default:if(!(o=c.trys,(o=o.length>0&&o[o.length-1])||6!==u[0]&&2!==u[0])){c=0;continue}if(3===u[0]&&(!o||u[1]>o[0]&&u[1]<o[3])){c.label=u[1];break}if(6===u[0]&&c.label<o[1]){c.label=o[1],o=u;break}if(o&&c.label<o[2]){c.label=o[2],c.ops.push(u);break}o[2]&&c.ops.pop(),c.trys.pop();continue}u=t.call(e,c)}catch(e){u=[6,e],r=0}finally{n=o=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}}var s=function(e){return"string"==typeof e},a=function(e){var t;return t=e||("undefined"==typeof fetch?o.default:fetch),function(){for(var e=[],n=0;n<arguments.length;n++)e[n]=arguments[n];return t.apply(void 0,e)}},d=function(e,n){var r=a(n),o="undefined"==typeof Headers?t.Headers:Headers;return function(t,n){return c(void 0,void 0,void 0,(function(){var c;return u(this,(function(u){return(c=new o(null==n?void 0:n.headers)).has("X-MICROCMS-API-KEY")||c.set("X-MICROCMS-API-KEY",e),[2,r(t,i(i({},n),{headers:c}))]}))}))}};exports.createClient=function(e){var t=e.serviceDomain,n=e.apiKey,o=e.customFetch;if(!t||!n)throw new Error("parameter is required (check serviceDomain and apiKey)");if(!s(t)||!s(n))throw new Error("parameter is not string");var i="https://".concat(t,".").concat("microcms.io","/api/").concat("v1"),a=function(e){var t=e.endpoint,s=e.contentId,a=e.queries,f=void 0===a?{}:a,l=e.method,v=e.customHeaders,p=e.customBody;return c(void 0,void 0,void 0,(function(){var e,a,h,w,y,m,b;return u(this,(function(E){switch(E.label){case 0:e=d(n,o),a=function(e){if(null===(t=e)||"object"!=typeof t)throw new Error("queries is not object");var t;return r.default.stringify(e,{arrayFormat:"comma"})}(f),h="".concat(i,"/").concat(t).concat(s?"/".concat(s):"").concat(a?"?".concat(a):""),E.label=1;case 1:return E.trys.push([1,5,,6]),[4,e(h,{method:l||"GET",headers:v,body:p})];case 2:return(w=E.sent()).ok?[3,4]:[4,c(void 0,void 0,void 0,(function(){var e;return u(this,(function(t){switch(t.label){case 0:return t.trys.push([0,2,,3]),[4,w.json()];case 1:return[2,null!=(e=t.sent().message)?e:null];case 2:return t.sent(),[2,null];case 3:return[2]}}))}))];case 3:return y=E.sent(),[2,Promise.reject(new Error("fetch API response status: ".concat(w.status).concat(y?"\n  message is `".concat(y,"`"):"")))];case 4:return"DELETE"===l?[2]:[2,w.json()];case 5:if((m=E.sent()).data)throw m.data;if(null===(b=m.response)||void 0===b?void 0:b.data)throw m.response.data;return[2,Promise.reject(new Error("Network Error.\n  Details: ".concat(m)))];case 6:return[2]}}))}))};return{get:function(e){var t=e.endpoint,n=e.contentId,r=e.queries,o=void 0===r?{}:r;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,contentId:n,queries:o})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},getList:function(e){var t=e.endpoint,n=e.queries,r=void 0===n?{}:n;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,queries:r})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},getListDetail:function(e){var t=e.endpoint,n=e.contentId,r=e.queries,o=void 0===r?{}:r;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,contentId:n,queries:o})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},getObject:function(e){var t=e.endpoint,n=e.queries,r=void 0===n?{}:n;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,queries:r})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},create:function(e){var t=e.endpoint,n=e.contentId,r=e.content,o=e.isDraft,i=void 0!==o&&o;return c(void 0,void 0,void 0,(function(){var e,o,c,s;return u(this,(function(u){return t?(e=i?{status:"draft"}:{},o=n?"PUT":"POST",c={"Content-Type":"application/json"},s=JSON.stringify(r),[2,a({endpoint:t,contentId:n,queries:e,method:o,customHeaders:c,customBody:s})]):[2,Promise.reject(new Error("endpoint is required"))]}))}))},update:function(e){var t=e.endpoint,n=e.contentId,r=e.content;return c(void 0,void 0,void 0,(function(){var e,o;return u(this,(function(i){return t?("PATCH",e={"Content-Type":"application/json"},o=JSON.stringify(r),[2,a({endpoint:t,contentId:n,method:"PATCH",customHeaders:e,customBody:o})]):[2,Promise.reject(new Error("endpoint is required"))]}))}))},delete:function(e){var t=e.endpoint,n=e.contentId;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?n?("DELETE",[4,a({endpoint:t,contentId:n,method:"DELETE"})]):[2,Promise.reject(new Error("contentId is required"))]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return e.sent(),[2]}}))}))}}};
^
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWljcm9jbXMtanMtc2RrLmpzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
Stack Trace
Error: parameter is required (check serviceDomain and apiKey)
    at exports.createClient (/home/tadashi/dev/astro_test/extinct-ellipse/node_modules/microcms-js-sdk/dist/cjs/microcms-js-sdk.js:1:2411)
    at clientFactoryFunction (/src/library/microcms.ts:6:32)
    at Module.getBlogs (/src/library/microcms.ts:12:18)
    at eval (/home/tadashi/dev/astro_test/extinct-ellipse/src/pages/blog.astro:22:71)
    at blog (/node_modules/astro/dist/runtime/server/astro-component.js:22:12)
    at renderPage (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/runtime/server/render/page.js:89:36)
    at renderPage (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/core/render/core.js:81:26)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async renderPage (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/core/render/dev/index.js:108:10)
    at async handleRoute (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/vite-plugin-astro-server/route.js:152:20)

It still did not seem to be reading the environment variables.

@excelsior091224
Copy link
Author

I was able to reproduce the error after renaming .env.

Error
An error occurred.
parameter is required (check serviceDomain and apiKey)
cjs/microcms-js-sdk.js:1:2411
Open in editor
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("qs"),t=require("cross-fetch");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=n(e),o=n(t),i=function(){return(i=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function c(e,t,n,r){return new(n||(n=Promise))((function(o,i){function c(e){try{s(r.next(e))}catch(e){i(e)}}function u(e){try{s(r.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(c,u)}s((r=r.apply(e,t||[])).next())}))}function u(e,t){var n,r,o,i,c={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;i&&(i=0,u[0]&&(c=0)),c;)try{if(n=1,r&&(o=2&u[0]?r.return:u[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,u[1])).done)return o;switch(r=0,o&&(u=[2&u[0],o.value]),u[0]){case 0:case 1:o=u;break;case 4:return c.label++,{value:u[1],done:!1};case 5:c.label++,r=u[1],u=[0];continue;case 7:u=c.ops.pop(),c.trys.pop();continue;default:if(!(o=c.trys,(o=o.length>0&&o[o.length-1])||6!==u[0]&&2!==u[0])){c=0;continue}if(3===u[0]&&(!o||u[1]>o[0]&&u[1]<o[3])){c.label=u[1];break}if(6===u[0]&&c.label<o[1]){c.label=o[1],o=u;break}if(o&&c.label<o[2]){c.label=o[2],c.ops.push(u);break}o[2]&&c.ops.pop(),c.trys.pop();continue}u=t.call(e,c)}catch(e){u=[6,e],r=0}finally{n=o=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}}var s=function(e){return"string"==typeof e},a=function(e){var t;return t=e||("undefined"==typeof fetch?o.default:fetch),function(){for(var e=[],n=0;n<arguments.length;n++)e[n]=arguments[n];return t.apply(void 0,e)}},d=function(e,n){var r=a(n),o="undefined"==typeof Headers?t.Headers:Headers;return function(t,n){return c(void 0,void 0,void 0,(function(){var c;return u(this,(function(u){return(c=new o(null==n?void 0:n.headers)).has("X-MICROCMS-API-KEY")||c.set("X-MICROCMS-API-KEY",e),[2,r(t,i(i({},n),{headers:c}))]}))}))}};exports.createClient=function(e){var t=e.serviceDomain,n=e.apiKey,o=e.customFetch;if(!t||!n)throw new Error("parameter is required (check serviceDomain and apiKey)");if(!s(t)||!s(n))throw new Error("parameter is not string");var i="https://".concat(t,".").concat("microcms.io","/api/").concat("v1"),a=function(e){var t=e.endpoint,s=e.contentId,a=e.queries,f=void 0===a?{}:a,l=e.method,v=e.customHeaders,p=e.customBody;return c(void 0,void 0,void 0,(function(){var e,a,h,w,y,m,b;return u(this,(function(E){switch(E.label){case 0:e=d(n,o),a=function(e){if(null===(t=e)||"object"!=typeof t)throw new Error("queries is not object");var t;return r.default.stringify(e,{arrayFormat:"comma"})}(f),h="".concat(i,"/").concat(t).concat(s?"/".concat(s):"").concat(a?"?".concat(a):""),E.label=1;case 1:return E.trys.push([1,5,,6]),[4,e(h,{method:l||"GET",headers:v,body:p})];case 2:return(w=E.sent()).ok?[3,4]:[4,c(void 0,void 0,void 0,(function(){var e;return u(this,(function(t){switch(t.label){case 0:return t.trys.push([0,2,,3]),[4,w.json()];case 1:return[2,null!=(e=t.sent().message)?e:null];case 2:return t.sent(),[2,null];case 3:return[2]}}))}))];case 3:return y=E.sent(),[2,Promise.reject(new Error("fetch API response status: ".concat(w.status).concat(y?"\n  message is `".concat(y,"`"):"")))];case 4:return"DELETE"===l?[2]:[2,w.json()];case 5:if((m=E.sent()).data)throw m.data;if(null===(b=m.response)||void 0===b?void 0:b.data)throw m.response.data;return[2,Promise.reject(new Error("Network Error.\n  Details: ".concat(m)))];case 6:return[2]}}))}))};return{get:function(e){var t=e.endpoint,n=e.contentId,r=e.queries,o=void 0===r?{}:r;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,contentId:n,queries:o})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},getList:function(e){var t=e.endpoint,n=e.queries,r=void 0===n?{}:n;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,queries:r})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},getListDetail:function(e){var t=e.endpoint,n=e.contentId,r=e.queries,o=void 0===r?{}:r;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,contentId:n,queries:o})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},getObject:function(e){var t=e.endpoint,n=e.queries,r=void 0===n?{}:n;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,queries:r})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},create:function(e){var t=e.endpoint,n=e.contentId,r=e.content,o=e.isDraft,i=void 0!==o&&o;return c(void 0,void 0,void 0,(function(){var e,o,c,s;return u(this,(function(u){return t?(e=i?{status:"draft"}:{},o=n?"PUT":"POST",c={"Content-Type":"application/json"},s=JSON.stringify(r),[2,a({endpoint:t,contentId:n,queries:e,method:o,customHeaders:c,customBody:s})]):[2,Promise.reject(new Error("endpoint is required"))]}))}))},update:function(e){var t=e.endpoint,n=e.contentId,r=e.content;return c(void 0,void 0,void 0,(function(){var e,o;return u(this,(function(i){return t?("PATCH",e={"Content-Type":"application/json"},o=JSON.stringify(r),[2,a({endpoint:t,contentId:n,method:"PATCH",customHeaders:e,customBody:o})]):[2,Promise.reject(new Error("endpoint is required"))]}))}))},delete:function(e){var t=e.endpoint,n=e.contentId;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?n?("DELETE",[4,a({endpoint:t,contentId:n,method:"DELETE"})]):[2,Promise.reject(new Error("contentId is required"))]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return e.sent(),[2]}}))}))}}};
^
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWljcm9jbXMtanMtc2RrLmpzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
Stack Trace
Error: parameter is required (check serviceDomain and apiKey)
    at exports.createClient (/home/tadashi/dev/astro_test/extinct-ellipse/node_modules/microcms-js-sdk/dist/cjs/microcms-js-sdk.js:1:2411)
    at clientFactoryFunction (/src/library/microcms.ts:6:32)
    at Module.getBlogs (/src/library/microcms.ts:12:18)
    at eval (/home/tadashi/dev/astro_test/extinct-ellipse/src/pages/blog.astro:22:71)
    at blog (/node_modules/astro/dist/runtime/server/astro-component.js:22:12)
    at renderPage (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/runtime/server/render/page.js:89:36)
    at renderPage (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/core/render/core.js:81:26)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async renderPage (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/core/render/dev/index.js:108:10)
    at async handleRoute (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/vite-plugin-astro-server/route.js:152:20)

It still did not seem to be reading the environment variables.

Sorry, this was an error.
I got the same error when I removed the Cloudflare adapter and started in SSG mode.
It seems impossible to reproduce this error with wrangler locally.

Error
An error occurred.
parameter is required (check serviceDomain and apiKey)
cjs/microcms-js-sdk.js:1:2411
Open in editor
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("qs"),t=require("cross-fetch");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=n(e),o=n(t),i=function(){return(i=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function c(e,t,n,r){return new(n||(n=Promise))((function(o,i){function c(e){try{s(r.next(e))}catch(e){i(e)}}function u(e){try{s(r.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(c,u)}s((r=r.apply(e,t||[])).next())}))}function u(e,t){var n,r,o,i,c={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;i&&(i=0,u[0]&&(c=0)),c;)try{if(n=1,r&&(o=2&u[0]?r.return:u[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,u[1])).done)return o;switch(r=0,o&&(u=[2&u[0],o.value]),u[0]){case 0:case 1:o=u;break;case 4:return c.label++,{value:u[1],done:!1};case 5:c.label++,r=u[1],u=[0];continue;case 7:u=c.ops.pop(),c.trys.pop();continue;default:if(!(o=c.trys,(o=o.length>0&&o[o.length-1])||6!==u[0]&&2!==u[0])){c=0;continue}if(3===u[0]&&(!o||u[1]>o[0]&&u[1]<o[3])){c.label=u[1];break}if(6===u[0]&&c.label<o[1]){c.label=o[1],o=u;break}if(o&&c.label<o[2]){c.label=o[2],c.ops.push(u);break}o[2]&&c.ops.pop(),c.trys.pop();continue}u=t.call(e,c)}catch(e){u=[6,e],r=0}finally{n=o=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}}var s=function(e){return"string"==typeof e},a=function(e){var t;return t=e||("undefined"==typeof fetch?o.default:fetch),function(){for(var e=[],n=0;n<arguments.length;n++)e[n]=arguments[n];return t.apply(void 0,e)}},d=function(e,n){var r=a(n),o="undefined"==typeof Headers?t.Headers:Headers;return function(t,n){return c(void 0,void 0,void 0,(function(){var c;return u(this,(function(u){return(c=new o(null==n?void 0:n.headers)).has("X-MICROCMS-API-KEY")||c.set("X-MICROCMS-API-KEY",e),[2,r(t,i(i({},n),{headers:c}))]}))}))}};exports.createClient=function(e){var t=e.serviceDomain,n=e.apiKey,o=e.customFetch;if(!t||!n)throw new Error("parameter is required (check serviceDomain and apiKey)");if(!s(t)||!s(n))throw new Error("parameter is not string");var i="https://".concat(t,".").concat("microcms.io","/api/").concat("v1"),a=function(e){var t=e.endpoint,s=e.contentId,a=e.queries,f=void 0===a?{}:a,l=e.method,v=e.customHeaders,p=e.customBody;return c(void 0,void 0,void 0,(function(){var e,a,h,w,y,m,b;return u(this,(function(E){switch(E.label){case 0:e=d(n,o),a=function(e){if(null===(t=e)||"object"!=typeof t)throw new Error("queries is not object");var t;return r.default.stringify(e,{arrayFormat:"comma"})}(f),h="".concat(i,"/").concat(t).concat(s?"/".concat(s):"").concat(a?"?".concat(a):""),E.label=1;case 1:return E.trys.push([1,5,,6]),[4,e(h,{method:l||"GET",headers:v,body:p})];case 2:return(w=E.sent()).ok?[3,4]:[4,c(void 0,void 0,void 0,(function(){var e;return u(this,(function(t){switch(t.label){case 0:return t.trys.push([0,2,,3]),[4,w.json()];case 1:return[2,null!=(e=t.sent().message)?e:null];case 2:return t.sent(),[2,null];case 3:return[2]}}))}))];case 3:return y=E.sent(),[2,Promise.reject(new Error("fetch API response status: ".concat(w.status).concat(y?"\n  message is `".concat(y,"`"):"")))];case 4:return"DELETE"===l?[2]:[2,w.json()];case 5:if((m=E.sent()).data)throw m.data;if(null===(b=m.response)||void 0===b?void 0:b.data)throw m.response.data;return[2,Promise.reject(new Error("Network Error.\n  Details: ".concat(m)))];case 6:return[2]}}))}))};return{get:function(e){var t=e.endpoint,n=e.contentId,r=e.queries,o=void 0===r?{}:r;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,contentId:n,queries:o})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},getList:function(e){var t=e.endpoint,n=e.queries,r=void 0===n?{}:n;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,queries:r})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},getListDetail:function(e){var t=e.endpoint,n=e.contentId,r=e.queries,o=void 0===r?{}:r;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,contentId:n,queries:o})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},getObject:function(e){var t=e.endpoint,n=e.queries,r=void 0===n?{}:n;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?[4,a({endpoint:t,queries:r})]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return[2,e.sent()]}}))}))},create:function(e){var t=e.endpoint,n=e.contentId,r=e.content,o=e.isDraft,i=void 0!==o&&o;return c(void 0,void 0,void 0,(function(){var e,o,c,s;return u(this,(function(u){return t?(e=i?{status:"draft"}:{},o=n?"PUT":"POST",c={"Content-Type":"application/json"},s=JSON.stringify(r),[2,a({endpoint:t,contentId:n,queries:e,method:o,customHeaders:c,customBody:s})]):[2,Promise.reject(new Error("endpoint is required"))]}))}))},update:function(e){var t=e.endpoint,n=e.contentId,r=e.content;return c(void 0,void 0,void 0,(function(){var e,o;return u(this,(function(i){return t?("PATCH",e={"Content-Type":"application/json"},o=JSON.stringify(r),[2,a({endpoint:t,contentId:n,method:"PATCH",customHeaders:e,customBody:o})]):[2,Promise.reject(new Error("endpoint is required"))]}))}))},delete:function(e){var t=e.endpoint,n=e.contentId;return c(void 0,void 0,void 0,(function(){return u(this,(function(e){switch(e.label){case 0:return t?n?("DELETE",[4,a({endpoint:t,contentId:n,method:"DELETE"})]):[2,Promise.reject(new Error("contentId is required"))]:[2,Promise.reject(new Error("endpoint is required"))];case 1:return e.sent(),[2]}}))}))}}};
^
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWljcm9jbXMtanMtc2RrLmpzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
Stack Trace
Error: parameter is required (check serviceDomain and apiKey)
    at exports.createClient (/home/tadashi/dev/astro_test/extinct-ellipse/node_modules/microcms-js-sdk/dist/cjs/microcms-js-sdk.js:1:2411)
    at clientFactoryFunction (/src/library/microcms.ts:6:32)
    at Module.getBlogs (/src/library/microcms.ts:12:18)
    at eval (/home/tadashi/dev/astro_test/extinct-ellipse/src/pages/blog.astro:22:71)
    at blog (/node_modules/astro/dist/runtime/server/astro-component.js:22:12)
    at renderPage (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/runtime/server/render/page.js:89:36)
    at renderPage (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/core/render/core.js:81:26)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async renderPage (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/core/render/dev/index.js:108:10)
    at async handleRoute (file:///home/tadashi/dev/astro_test/extinct-ellipse/node_modules/astro/dist/vite-plugin-astro-server/route.js:152:20)

@Diewy
Copy link

Diewy commented Mar 15, 2023

@excelsior091224 I'm having the same issue, have you been able to fix it?

@excelsior091224
Copy link
Author

@excelsior091224 I'm having the same issue, have you been able to fix it?

no.

@excelsior091224
Copy link
Author

Solution is found.
We could use getRuntime in @astrojs/cloudflare/runtime to get the environment variables from Astro.request.

import { getRuntime } from "@astrojs/cloudflare/runtime";
const generateClient = (request: Request) => {
  // runtimeの中にはenvの他、KVなど他のサービスなどがコンテキストとして入ってくる
  const runtime = getRuntime(request);
  //@ts-expect-error envの型は適宜調整
  const { MICROCMS_SERVICE_DOMAIN, MICROCMS_API_KEY } = runtime.env;
  return createClient({
    serviceDomain: MICROCMS_SERVICE_DOMAIN,
    apiKey: MICROCMS_API_KEY,
  });
};

https://zenn.dev/tnakamoto/articles/771b0f3af050d8

@nindalf
Copy link

nindalf commented Mar 31, 2024

Good solution by excelsior. I'd suggest one change

const runtime = Astro.locals.runtime;
const { YOUR_API_KEY } = runtime.env;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants