Components are pieces of HTML, CSS, and JS that can be added to posts or other components. They allow for customization by giving users custom fields to input data into. This post will discuss all parts of a component.
Title
The title is required, and must be 4 to 20 characters long.
Description
The description is required, and must be 20 to 255 characters. It appears in searches, so it should describe the purpose it serves, and any benefits and limits to using it. For instance, if you were creating a bar graph, it would be useful to mention if it allows for certain customizations such as colors of the bars, and if there is a limit on the number of bar that may be added.
Details
The details section is optional. It displays after a component has been selected, and above the data that is requested from the user. Relevant info about how the component works, and customization options go here. Continuing with the bar graph example, you could write that if a bar color is not specified, blue is used, and that for customization, the bars have the class 'bar' that may be edited by adding a <style> element to their post.
Line breaks are conserved in details, so you can separate topics into different parts.
User-Entered Data
User-Entered Data is also optional. When used, each field in the row is required. The fields are:
All user-entered data becomes a part of an object for your code. Each component has a unique id, and this id is embedded into the source variable name of this user-entered data object. If the component's id is iOK0H, the source variable for your component is dataiOK0H (will be used as an example throughout this doc). This is still the variable name you should use in your code when accessing component data.
Each component also has a config object named dataiOK0H_config. It includes created, previewHtml, componentId, and localId. On the full post page it also includes fragment, which is the current url fragment without the leading #.
Component Collisions
To allow for multiple instances of your component to be added to one post, every instance of dataiOK0H is still rewritten before your code runs so that each instance gets its own runtime variable. Use dataiOK0H in your source code so the system can rewrite it correctly.
When a component is added to a post, it is given a localId (starts at 0 and auto-increments). This localId is visible in the code editor, so the user can use it if necessary (described later). If your component is the third added, it will have a localId of 2. Before your code is run, instances of dataiOK0H are rewritten to a runtime-specific variable that includes the localId, and it may also include an added random string. Because of that, do not depend on the final rewritten variable name being stable across renders.
If you need stable values for ids, class names, fragment targets, or other generated markup, use dataiOK0H_config.componentId and dataiOK0H_config.localId.
Style customization of components
You can let users custom style your components by mentioning class names and ids in the Detail section of the component page. If you want those selectors to stay stable, build them from dataiOK0H_config.componentId and dataiOK0H_config.localId instead of depending on the final rewritten runtime variable name. So if your class is based on those stable config values, users can target it reliably without worrying about runtime rewriting.
Approval of components
Unlike posts, components cannot be used or seen in search results until they are approved. This is to prevent malicious code from becoming widespread before being deleted, and potentially diminishing the UX for users visiting posts that had a component deleted retroactively. To ensure your component is approved, refrain from using external JS files that could be changed maliciously in the future. Only repositories on unpkg.com - like jQuery, React, and other npm packages - will be allowed. Aside from common social media, all other script urls are blocked by our Content-Security-Policy. If you have another site you'd like to include scripts from, please submit feedback (in the dropdown menu in the upper right hand corner when you log in).
Add the following to enable react:
<script src='https://unpkg.com/react/umd/react.production.min.js'></script> <script src='https://unpkg.com/react-dom/umd/react-dom.production.min.js'></script>
When testing, use the following:
<script src='https://unpkg.com/react/umd/react.development.js'></script> <script src='https://unpkg.com/react-dom/umd/react-dom.development.js'></script>
Versioning
When a new version of a component is approved, changes will not automatically propagate to posts using that component. Posts will have to be updated individually. This was done because updated components may no longer fit in as well with the post, and can change user-entered data formatting.
Coding details
Use dataiOK0H for your component's actual data. Use dataiOK0H_config.componentId and dataiOK0H_config.localId when you need stable html ids, class names, or fragment targets.
const sectionId = `${dataiOK0H_config.componentId}-${dataiOK0H_config.localId}-results`;On the full post page, dataiOK0H_config.fragment contains the current url fragment without the leading #. This can be used if your component needs to react to a specific fragment when the post is opened.
Store Data
If you choose the Store Data field type, that field must be at the top level. Store Data lets a component load saved values for the current user and aggregate values returned by the backend. The configured keys for that field become data properties, and those keys may only contain letters, numbers, and underscores.
At runtime, call fgStoreData or formOfGoodStoreData. Both return a Promise. On success, the requested property on your component data object is updated with an object containing userInput and aggregateValues.
fgStoreData('load', 'dataiOK0H', 'scores').then(function () { console.log(dataiOK0H.scores.userInput); console.log(dataiOK0H.scores.aggregateValues); });fgStoreData('save', 'dataiOK0H', 'scores', 7).then(function () { console.log(dataiOK0H.scores.userInput); });Saving requires the user to be logged in. In previews, Store Data uses the configured test payload until the component is attached to a post.
Linking to fragments in posts
If you want a button or link inside a rendered component to open the full post and jump to a specific element, add data-click-bridge-fragment to the clicked element. The value should match the target element's id, with or without the leading #.
<button data-click-bridge-fragment='results-section'>View Results</button> <a href='#' data-click-bridge-fragment='results-section'>View Results</a>
The target element should use a stable id, ideally one built from dataiOK0H_config.componentId and dataiOK0H_config.localId. If you only want to open the post without adding a hash, use data-click-bridge-navigate.
Caveats
Single Page App with Server Side Rendering
Because pages are loaded two different ways, you must plan accordingly. If you need to wait for the page to load to examine or manipulate elements, you will have to check to see if the document has loaded already before adding a window load event listener:
// when using React componentDidMount() { if (document.readyState !== 'complete') { this.listenerSet = true; window.addEventListener('load', this.loadData); } else { this.listenerSet = false; this.loadData(); } }For removing the listener in React:
componentWillUnmount() { if (this.listenerSet) { window.removeEventListener('load', this.loadData); } }Without React:
if (document.readyState !== 'complete') { window.addEventListener('beforeunload', function (event) { window.removeEventListener('load', this.loadData); }); }