contentful-typescript-codegen icon indicating copy to clipboard operation
contentful-typescript-codegen copied to clipboard

Smooth integration with next.js , env.local and alternative to getContentfulEnvironment

Open Carduelis opened this issue 4 years ago • 5 comments

Hello! First of all, would like to say that your app is a game changer for contentful.

I'm using Next.js (Commerce variant) and would like to have a smooth way to adopt your package.

First, of all, for the sake of security we aim to store environment variables in env.local file which is out of git control. It's a common approach and also is adoped in next.js ecosystem.

So, it's not automatically works with env.local, which should be fixed on the library level.

And the second, I would like to have an alternative to a commonjs syntax of getContentfulEnvironment and the file itself. The problem is I have to duplicate client setup logic in typescript and then in javascript only for your library.

Thanks!

Carduelis avatar Oct 17 '21 13:10 Carduelis

Altough, even .env file doesn't work with your library on windows.

Carduelis avatar Oct 17 '21 13:10 Carduelis

For those who on windows. Install dotenv and then add the config injection like this:

const contentfulManagement = require('contentful-management')
require('dotenv').config() // <-- here is the trick

module.exports = function () {
  const contentfulClient = contentfulManagement.createClient({
    accessToken: process.env.PRIVATE_CONTENTFUL_MANAGEMENT_ACCESS_TOKEN,
  })

  return contentfulClient
    .getSpace(process.env.PRIVATE_CONTENTFUL_SPACE_ID)
    .then((space) =>
      space.getEnvironment(process.env.PRIVATE_CONTENTFUL_ENVIRONMENT_ID)
    )
}

Carduelis avatar Oct 17 '21 13:10 Carduelis

If you don't want to install any additional dependencies you can use nextjs env library directly

const { loadEnvConfig } = require("@next/env");
const contentful = require("contentful-management");

module.exports = async function() {
  loadEnvConfig(process.env.PWD);

  const client = contentful.createClient({
    accessToken: process.env.CONTENTFUL_MANAGEMENT_TOKEN,
  })

  return client
    .getSpace(process.env.CONTENTFUL_SPACE_ID)
    .then(space => space.getEnvironment(process.env.CONTENTFUL_ENVIRONMENT))
}

Maxwell2022 avatar Aug 09 '22 22:08 Maxwell2022

Hello, I am having an issue with the Image component from Next and typescript. I have types like this

// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY IT.

import { Asset, Entry } from "contentful";

export interface ITheyTrustUsCompaniesFields {
  /** name */
  name?: string | undefined;

  /** icon */
  icon?: Asset | undefined;
}

/** These are the companies that trust *** with building complex web and mobile applications. */

export interface ITheyTrustUsCompanies
  extends Entry<ITheyTrustUsCompaniesFields> {
  sys: {
    id: string;
    type: string;
    createdAt: string;
    updatedAt: string;
    locale: string;
    contentType: {
      sys: {
        id: "theyTrustUsCompanies";
        linkType: "ContentType";
        type: "Link";
      };
    };
  };
}

export type CONTENT_TYPE = "theyTrustUsCompanies";

export type IEntry = ITheyTrustUsCompanies;

export type LOCALE_CODE = "en-US";

export type CONTENTFUL_DEFAULT_LOCALE_CODE = "en-US";

But I need to do "as string" when I want to use image the asset like so, I would like to not have to do this on every single image, right?

<Image
       src={item.icon?.fields.file?.url as string}
       alt={item.icon?.fields.description as string}
       width="200"
       height="85"
/>

The error message I get if I don't is: Type 'string | AssetFile | undefined' is not assignable to type 'string | StaticImport'. but I cannot modify the generated file to change the type, how should I go about this? I'm asking here because it is related to NextJS, I hope that is fine, I can create a stack overflow question or another issue with no problems.

Thanks

leimeter-joaquin avatar May 01 '23 21:05 leimeter-joaquin

That's not a NextJS issue, your types looks fine. I think it's because your icon is optional in contentful, hence the URL to the icon image can be undefined.

If you cannot change this then you need to check if it's set before loading your image

const icon = item.icon?.fields.file?.url;

if (!icon) {
  return null;
}

return <Image
       src={icon}
       alt={item.icon?.fields.description || 'no description'}
       width="200"
       height="85"
/>

Maxwell2022 avatar May 02 '23 03:05 Maxwell2022