apostrophe: settings: alias is not a valid top level property for an Apostrophe 3.x module

If following the steps described at An alternative approach: environment variables.

// in app.js

modules: {
  settings: {
    alias: 'settings',
    analyticsId: process.env.ANALYTICS_ID
  }
  // ... other modules, etc.
}

This output is displayed:

...
settings: alias is not a valid top level property for an Apostrophe 3.x module. Make sure you nest regular module options in the new "options" property.
[nodemon] app crashed - waiting for file changes before starting...
...

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 17 (8 by maintainers)

Most upvoted comments

Finally I just created a basic “piece type” module called product as described in Code organization with modules and wrote this code to make an API call using environment vars.

// in modules/product/index.js

const axios = require('axios');

require('dotenv').config();

module.exports = {
  extend: '@apostrophecms/piece-type',
  components(self) {
    return {
      async list(req) {
        let products = [];
        const myApiRes = await axios.post(`${process.env.MY_API_URL}/products/list`, {
          my_api_key: process.env.MY_API_KEY,
          my_api_auth: process.env.MY_API_AUTH,
        });
        products = myApiRes.data.response;
        return {
          products
        };
      }
    };
  }
}; 

The article module in apostrophecms/a3-demo was also helpful to learn about “piece type” modules. It seems as if I don’t even have to change the app.js file to work with environment variables. An .env file being loaded with dotenv is okay.

I’m not entirely sure of your end goal. I know you want to fetch some data, but could you let me know if there is a specific reason to do so client side? Is there a reason you can’t fetch it browser side during the render? If you can do that, take a look at asynchronous components. You can use process.env all you like without fear of exposing secrets.

Environment variables are only secrets as long as they stay browser side. If you have to do it client side you can set-up some middleware that completes the request. Finally, maybe your API has provisions for obtaining a token server side that can be exposed client side without causing a security breach.

Cheers, Bob

Yes, an async component is a good place to do that. Alternatively, if you wanted to trigger it later from browser side JS, you could create an “apiRoute” that makes that call on the user’s behalf from the server, and use apos.http.get or “fetch” or whatever you prefer to talk to it.

On Thu, Mar 16, 2023 at 8:27 AM Jordi Bassaganas @.***> wrote:

Thanks for pointing out:

Take a look at asynchronous components. You can use process.env all you like without fear of exposing secrets.

Everything’s clear now.

This API call with a secret in the POST header needs to be made in an async component.

— Reply to this email directly, view it on GitHub https://github.com/apostrophecms/apostrophe/issues/4095#issuecomment-1471866563, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAH27MVL3MHDNCY5VXCCLDW4MBJZANCNFSM6AAAAAAV4FMFME . You are receiving this because you were mentioned.Message ID: @.***>

THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER APOSTROPHECMS | apostrophecms.com | he/him/his

Any template file that extends another can only output markup inside a Nunjucks block that is defined in the original template (layout.html in this case). In this case the example you give overrides the main block. You could put a script tag in there, if you wanted. Nunjucks doesn’t really know or care what tags you emit, it just emits what you ask it to, which can include script tags.

Indeed, if you want to expose information to the browser side this is helpful:

<script> window.myVariable = {{ apos.settings.getOption('foobar') | json }}; </script>

The “json” Nunjucks filter will take what it’s given and escape it correctly as (1) JSON, and (2) safe for inclusion in a script tag.

So what the browser actually receives (and you see in “page source”) will be:

<script> window.myVariable = "some actual value"; </script>

Note this works for data structures too, not just strings.

On Wed, Mar 15, 2023 at 4:08 PM Robert Means @.***> wrote:

You have to think about “where” you are, server-side or client-side. Your script tag is being delivered to the browser where it is the executed. But the browser doesn’t know anything about the server-side apos. Is it important that the environment variable value not be exposed?

— Reply to this email directly, view it on GitHub https://github.com/apostrophecms/apostrophe/issues/4095#issuecomment-1470767073, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAH27I6DVLUQ7YAGQYFKJTW4IOUBANCNFSM6AAAAAAV4FMFME . You are receiving this because you commented.Message ID: @.***>

THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER APOSTROPHECMS | apostrophecms.com | he/him/his

You have to think about “where” you are, server-side or client-side. Your script tag is being delivered to the browser where it is the executed. But the browser doesn’t know anything about the server-side apos. Is it important that the environment variable value not be exposed?

Sorry, missed your second comment

Also it’d be nice to check out a sample Apostrophe site on GitHub.

There is the a3-demo site you can check out. https://github.com/apostrophecms/a3-demo A lot of the components in this repo are broken up into multiple files, looking at you button-widget! I’ve found that a lot of people try to use this demo by copying the module and then not getting the rest of the supporting files copied over. The button-widget module makes use of a file in the top-most lib folder and an HTML/Nunjucks macro file in the views folder. Just be aware of that.

To simplify your life you can also use {{ apos.log('text', variable) }} directly in the template.

~What version of Apostrophe are you using?~ Just saw the title. You are looking at the Apostrophe 2.X documentation based on the link.