Install headless Optimizely Forms JavaScript SDK for the client app
Precondition: npm install -g typescript
-
Create a React app template.
npx create-react-app headless-form --template typescript cd headless-form
-
Install Javascript SDK. Create a file
.npmrc
with content to download the package from GitHub.@episerver:registry=https://pkgs.dev.azure.com/EpiserverEngineering/netCore/_packaging/HeadlessForms/npm/registry
npm install @episerver/forms-sdk @episerver/forms-react react-router-dom @types/react-router-dom
Note
Replace the
react-router-dom
withversion =5.3.4
. -
Create file .env with content.
REACT_APP_ENDPOINT_GET_FORM_BY_PAGE_URL=http://localhost:8000/api/React/GetFormInPageByUrl?url= REACT_APP_HEADLESS_FORM_BASE_URL=http://localhost:8000/ REACT_APP_AUTH_BASEURL=http://localhost:8000/api/episerver/connect/token
-
Add code to
\src\App.tsx
.import "./App.css"; import { useFetch } from "./useFetch"; import { Form, FormLogin } from "@episerver/forms-react"; import { FormCache, FormConstants, IdentityInfo, extractParams, } from "@episerver/forms-sdk"; import { useState } from "react"; import { useHistory, useLocation } from "react-router-dom"; function App() { const location = useLocation(); const { language } = extractParams(window.location.pathname); const url = `${process.env.REACT_APP_ENDPOINT_GET_FORM_BY_PAGE_URL}${location.pathname}`; const { data: pageData, loading } = useFetch(url); const formCache = new FormCache(); const [identityInfo, setIdentityInfo] = useState<IdentityInfo>({ accessToken: formCache.get<string>(FormConstants.FormAccessToken), } as IdentityInfo); const history = useHistory(); const handleAuthen = (identityInfo: IdentityInfo) => { setIdentityInfo(identityInfo); }; return ( <div className="App"> {loading && <div className="loading">Loading...</div>} {!loading && pageData && ( <> <h1>{pageData.title}</h1> <div className="main"> <div className="left"> {pageData.formKeys.map((c: any) => ( <Form key={c.reference.key} formKey={c.reference.key} language={language ?? "en"} baseUrl={process.env.REACT_APP_HEADLESS_FORM_BASE_URL ?? "/"} identityInfo={identityInfo} history={history} currentPageUrl={pageData.pageUrl} /> ))} </div> <div className={`right`}> <h2>Login</h2> <FormLogin clientId="TestClient" authBaseUrl={process.env.REACT_APP_AUTH_BASEURL ?? ""} onAuthenticated={handleAuthen} /> </div> </div> </> )} </div> ); } export default App;
-
Remove
App.test.tsx
file. -
Update code
\src\index.tsx
.import React from "react"; import ReactDOM from "react-dom/client"; import "./index.css"; import App from "./App"; import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; const root = ReactDOM.createRoot( document.getElementById("root") as HTMLElement ); root.render( <React.StrictMode> <Router> <Switch> <Route path="/"> <App /> </Route> </Switch> </Router> </React.StrictMode> );
-
Add file
\src\useFetch.ts
.import { useEffect, useState } from "react"; export const useFetch = (url: string) => { const [data, setData] = useState<any>(null); const [loading, setLoading] = useState<boolean>(false); const [error, setError] = useState<any>(null); useEffect(() => { const fetchData = async () => { setLoading(true); fetch(url) .then(async (response: Response) => { if (response.ok) { setData(await response.json()); } }) .catch((err: any) => { setError(err); }) .finally(() => { setLoading(false); }); }; if (!loading) { fetchData(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [url]); return { data, loading, error }; };
-
Run client site.
npm start
-
Change the
frontend
's port toClientApp
's port onManagementSite
.- Update
appsettings.json
file. - Update on Manage Websites.
- Use http instead of https on
launchSettings.json
.
- Update
Updated about 2 months ago