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
.npmrcwith 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-domNoteReplace the
react-router-domwithversion =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.tsxfile. -
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.jsonfile. - Update on Manage Websites.
- Use http instead of https on
launchSettings.json.
- Update
Updated about 2 months ago