Skip to content

Commit

Permalink
Merge pull request #223 from kontent-ai/add_context_for_client
Browse files Browse the repository at this point in the history
Add context for client
  • Loading branch information
IvanKiral authored May 19, 2023
2 parents 269085e + 27d82b8 commit ed95df6
Show file tree
Hide file tree
Showing 21 changed files with 750 additions and 684 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
REACT_APP_PROJECT_ID=your_project_id
REACT_APP_ENVIRONMENT_ID=your_environment_id
REACT_APP_PREVIEW_API_KEY=your_api_key
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ If you want to change the source Kontent.ai project, follow these steps:

1. In Kontent.ai, choose Project settings from the app menu.
2. Under Development, choose API keys.
3. Copy your Project ID.
3. Copy your Environemnt ID.
4. Open `.env.example` in the root directory.
5. Replace `your_project_id` with your Project ID and remove `REACT_APP_PREVIEW_API_KEY` entry.
5. Replace `your_environment_id` with your Environment ID and remove `REACT_APP_PREVIEW_API_KEY` entry.
6. Save and rename the file `.env`.

When you now run the sample application, the application retrieves content from your project.
Expand All @@ -44,15 +44,15 @@ Deploy, explore and change the app directly in the browser.

## Previewing content from your project

If you already have a Kontent.ai account and you want to connect the sample application to a project of your own, you need to provide your Project ID and your Preview API key to authorize requests to the Delivery Preview API. For example, you can connect the application to your modified version of the sample project.
If you already have a Kontent.ai account and you want to connect the sample application to a project of your own, you need to provide your Environment ID and your Preview API key to authorize requests to the Delivery Preview API. For example, you can connect the application to your modified version of the sample project.

To preview content in the sample application, follow these steps:

1. In Kontent.ai, choose Project settings from the app menu.
2. Under Development, choose API keys.
3. Copy your Project ID and Preview API key.
3. Copy your Environemnt ID and Preview API key.
4. Open `.env.example` in the root directory .
5. Replace `your_project_id` and `your_api_key` with your Project ID and Preview API key.
5. Replace `your_environment_id` and `your_api_key` with your Environment ID and Preview API key.
6. Save and rename the file `.env`.

When you now run the application, you will see all project content including the unpublished version of content items.
Expand All @@ -69,8 +69,8 @@ You can learn more about content editing in our tutorials at [Kontent.ai Learn](

You can retrieve content either through the Kontent.ai Delivery SDKs or the Kontent.ai Delivery API:

- For published content, use `https://deliver.kontent.ai/PROJECT_ID/items`.
- For unpublished content, use `https://preview-deliver.kontent.ai/PROJECT_ID/items`.
- For published content, use `https://deliver.kontent.ai/ENVIRONMENT_ID/items`.
- For unpublished content, use `https://preview-deliver.kontent.ai/ENVIRONMENT_ID/items`.

For more info about the API, see the [API reference](https://kontent.ai/learn/reference).

Expand Down
938 changes: 478 additions & 460 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@
"typescript": "^4.8.4"
},
"dependencies": {
"@kontent-ai/delivery-sdk": "^12.0.2",
"@kontent-ai/react-components": "0.1.1",
"@kontent-ai/delivery-sdk": "^14.0.1",
"@kontent-ai/react-components": "0.3.0",
"@simply007org/react-spinners": "0.0.3",
"qs": "^6.9.4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet": "^6.0.0",
"react-intl": "^5.24.8",
"react-router-dom": "6.3.0",
"react-intl": "^6.4.0",
"react-router-dom": "6.10.0",
"universal-cookie": "^4.0.4",
"validator": "^13.7.0"
},
Expand All @@ -46,7 +46,7 @@
"not op_mini all"
],
"engines": {
"npm": "7 || 8",
"node": "16 || 17"
"npm": "8 || 9",
"node": "18"
}
}
14 changes: 9 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import Coffee from './Pages/Coffee';
import Brewer from './Pages/Brewer';
import { SetLanguageType } from './LocalizedApp';
import { NotFound } from './Pages/NotFound';
import { getProjectIdFromCookies, getProjectIdFromEnvironment } from './Client';
import {
getEnvironmentIdFromCookies,
getEnvironmentIdFromEnvironment,
} from './Client';
import { projectConfigurationPath } from './const';

interface AppProps {
Expand All @@ -28,17 +31,18 @@ interface AppProps {
const App: React.FC<AppProps> = ({ changeLanguage }) => {
const { formatMessage } = useIntl();

if (getProjectIdFromEnvironment() === null) {
if (getEnvironmentIdFromEnvironment() === null) {
return (
<div>
Your projectId given in your environment variables is not a valid GUID.
Your environmentId given in your environment variables is not a valid
GUID.
</div>
);
}

if (
getProjectIdFromEnvironment() === undefined &&
!getProjectIdFromCookies()
getEnvironmentIdFromEnvironment() === undefined &&
!getEnvironmentIdFromCookies()
) {
return <Navigate to={projectConfigurationPath} />;
}
Expand Down
95 changes: 0 additions & 95 deletions src/Client.ts

This file was deleted.

113 changes: 113 additions & 0 deletions src/Client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import Cookies from 'universal-cookie';
import {
camelCasePropertyNameResolver,
DeliveryClient,
} from '@kontent-ai/delivery-sdk';
import packageInfo from '../package.json';
import { selectedEnvironmentCookieName } from './const';
import validator from 'validator';
import {
createContext,
FC,
PropsWithChildren,
useCallback,
useContext,
useMemo,
useState,
} from 'react';

const sourceTrackingHeaderName = 'X-KC-SOURCE';

const previewApiKey = process.env.REACT_APP_PREVIEW_API_KEY || '';

const cookies = new Cookies(document.cookie);

const getEnvironmentIdFromEnvironment = (): string | null | undefined => {
const environmentIdFromEnv = process.env.REACT_APP_ENVIRONMENT_ID;

if (environmentIdFromEnv && !validator.isUUID(environmentIdFromEnv)) {
console.error(
`Your environmentId (${environmentIdFromEnv}) given in your environment variables is not a valid GUID.`
);
return null;
}

return environmentIdFromEnv;
};

const getEnvironmentIdFromCookies = (): string | null => {
const environmentIdFromCookie = cookies.get(selectedEnvironmentCookieName);

if (environmentIdFromCookie && !validator.isUUID(environmentIdFromCookie)) {
console.error(
`Your environmentId (${environmentIdFromCookie}) from cookies is not a valid GUID.`
);
return null;
}

return environmentIdFromCookie;
};

const currentEnvironmentId =
getEnvironmentIdFromEnvironment() ?? getEnvironmentIdFromCookies() ?? '';

const isPreview = (): boolean => previewApiKey !== '';

type GlobalHeadersType = {
header: string;
value: string;
};

const createClient = (newEnvironmentId: string): DeliveryClient =>
new DeliveryClient({
environmentId: newEnvironmentId,
previewApiKey: previewApiKey,
defaultQueryConfig: {
usePreviewMode: isPreview(),
},
globalHeaders: (_queryConfig): GlobalHeadersType[] => [
{
header: sourceTrackingHeaderName,
value: `${packageInfo.name};${packageInfo.version}`,
},
],
propertyNameResolver: camelCasePropertyNameResolver,
});

const Client = createClient(currentEnvironmentId);

type ClientState = [DeliveryClient, (environmentId: string) => void];

const ClientContext = createContext<ClientState>(undefined as never);

export const useClient = (): ClientState => useContext(ClientContext);

export const ClientProvider: FC = ({
children,
}: PropsWithChildren<unknown>) => {
const [client, setClient] = useState(Client);

const updateClient = useCallback((newEnvironmentId: string) => {
setClient(createClient(newEnvironmentId));

cookies.set(selectedEnvironmentCookieName, newEnvironmentId, {
path: '/',
sameSite: 'none',
secure: true,
});
}, []);

return (
<ClientContext.Provider
value={useMemo(() => [client, updateClient], [client, updateClient])}
>
{children}
</ClientContext.Provider>
);
};

export {
createClient,
getEnvironmentIdFromEnvironment,
getEnvironmentIdFromCookies,
};
10 changes: 6 additions & 4 deletions src/Components/BrewerStoreContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { spinnerService } from '@simply007org/react-spinners';
import React, { useEffect } from 'react';
import { useState } from 'react';
import { Client } from '../Client';
import { matchesTaxonomy } from '../Utilities/CheckboxFilter';
import {
defaultLanguage,
Expand All @@ -13,6 +12,7 @@ import { ITaxonomyTerms } from '@kontent-ai/delivery-sdk';
import { useIntl } from 'react-intl';
import { Brewer } from '../Models/content-types/brewer';
import { contentTypes } from '../Models/project/contentTypes';
import { useClient } from '../Client';

interface filterType {
[index: string]: string[];
Expand Down Expand Up @@ -43,6 +43,8 @@ const BrewerStoreContainer: React.FC = () => {
productStatuses: [],
});

const [Client] = useClient();

useEffect(() => {
spinnerService.show('apiSpinner');

Expand All @@ -63,23 +65,23 @@ const BrewerStoreContainer: React.FC = () => {
[currentLanguage]: response.data.items as Brewer[],
}));
});
}, [language]);
}, [language, Client]);

useEffect(() => {
Client.taxonomy('manufacturer')
.toPromise()
.then((response) => {
setManufacturers(response.data.taxonomy.terms);
});
}, []);
}, [Client]);

useEffect(() => {
Client.taxonomy('product_status')
.toPromise()
.then((response) => {
setProductStatuses(response.data.taxonomy.terms);
});
}, []);
}, [Client]);

const matches = (brewer: Brewer): boolean =>
matchesTaxonomy(brewer, filter.manufacturers, 'manufacturer') &&
Expand Down
Loading

0 comments on commit ed95df6

Please sign in to comment.