UNPKG

@dotcms/react

Version:

Official React Components library to render a dotCMS page.

136 lines (133 loc) 4.34 kB
import { useState, useEffect } from 'react'; import { UVEEventType } from '@dotcms/types'; import { getUVEState, initUVE, updateNavigation, createUVESubscription } from '@dotcms/uve'; import { registerStyleEditorSchemas } from '@dotcms/uve/internal'; /** * Custom hook to manage the editable state of a DotCMS page. * * This hook initializes the Universal Visual Editor (UVE) and subscribes to content changes. * It updates the editable page state when content changes are detected in the UVE, * ensuring your React components always display the latest content when editing in DotCMS. * * @example * ```ts * // Import the hook and the client * import { useEditableDotCMSPage } from '@dotcms/react'; * import { createDotCMSClient } from '@dotcms/client'; * * // Create the client * const client = createDotCMSClient({ * dotcmsURL: 'https://your-dotcms-instance.com', * authToken: 'your-auth-token' * }); * * // Get the page * const page = await client.page.get('/', { * languageId: '1', * }); * * // Use the hook to get an editable version of the page * const editablePage = useEditableDotCMSPage(page); * * // Then use the page data in your component * return ( * <div> * <h1>{editablePage.page.title}</h1> * <div dangerouslySetInnerHTML={{ __html: editablePage.page.body }} /> * </div> * ); * ``` * * @example * ```ts * // Import the hook and the client * import { useEditableDotCMSPage } from '@dotcms/react'; * import { createDotCMSClient } from '@dotcms/client'; * * // Create the client * const client = createDotCMSClient({ * dotcmsURL: 'https://your-dotcms-instance.com', * authToken: 'your-auth-token' * }); * * // Get the page with GraphQL content * const page = await client.page.get('/', { * languageId: '1', * graphql: { * content: { * products: `ProductCollection(query: "+title:snow", limit: 10, offset: 0, sortBy: "score") { * title * urlMap * category { * name * inode * } * retailPrice * image { * versionPath * } * }` * } * } * }); * * // Use the hook to get an editable version of the page and its content * const editablePage = useEditableDotCMSPage(page); * * // Access both page data and GraphQL content * const { page: pageData, content } = editablePage; * * // Use the products from GraphQL content * return ( * <div> * <h1>{pageData.title}</h1> * <ProductList products={content.products} /> * </div> * ); * ``` * @param {DotCMSPageResponse} pageResponse - The initial editable page data from client.page.get(). * * @returns {DotCMSPageResponse} The updated editable page state that reflects any changes made in the UVE. * The structure includes page data and any GraphQL content that was requested. */ const useEditableDotCMSPage = pageResponse => { const [updatedPageResponse, setUpdatedPageResponse] = useState(pageResponse); useEffect(() => { var _pageResponse$pageAss, _pageResponse$styleEd; if (!getUVEState()) { return; } if (!pageResponse) { console.warn('[useEditableDotCMSPage]: No DotCMSPageResponse provided'); return; } const pageURI = pageResponse == null || (_pageResponse$pageAss = pageResponse.pageAsset) == null || (_pageResponse$pageAss = _pageResponse$pageAss.page) == null ? void 0 : _pageResponse$pageAss.pageURI; const { destroyUVESubscriptions } = initUVE(pageResponse); // Update the navigation to the pageURI, when we have a pageURI // Sometimes the page is null due to permissions, so we don't want to update the navigation // And wait for the UVE to resolve the page if (pageURI) { updateNavigation(pageURI); } if ((_pageResponse$styleEd = pageResponse.styleEditorSchemas) != null && _pageResponse$styleEd.length) { registerStyleEditorSchemas(pageResponse.styleEditorSchemas); } return () => { destroyUVESubscriptions(); }; }, [pageResponse]); useEffect(() => { const { unsubscribe } = createUVESubscription(UVEEventType.CONTENT_CHANGES, payload => { setUpdatedPageResponse(payload); }); return () => { unsubscribe(); }; }, []); return updatedPageResponse; }; export { useEditableDotCMSPage };