@livingdocs/node-sdk
v2.0.14
Published
Livingdocs SDK
Downloads
855
Readme
livingdocs-sdk
The official Node.js client for Livingdocs. This is a low-level library. If you're looking for a full-fledged use case, consider taking a look at our magazine example
Also, check out our service documentation at https://developers.livingdocs.io
Prerequisites
- Minimum Node version: 14
- Read the Changelog to get up to date
Getting started
We assume, you already have an account on https://edit.livingdocs.io If not, create one now.
You can also check the full example in runkit, but make sure to replace the API token with your own: https://runkit.com/gabriel-hase/livingdocs-first-steps
- Install the SDK
npm install @livingdocs/node-sdk
- Get your access token from
edit.livingdocs.io
by navigating toAccess Management
->Api Tokens
- Get a document
const liSDK = require('@livingdocs/node-sdk')
const liClient = new liSDK.Client({
url: 'https://server.livingdocs.io',
accessToken: 'my-awesome-token'
})
// you can see the document id in the URL of an article in the Livingdocs Editor
const publication = await liClient.getPublication({documentId: 1})
We assume that you used the standard signup flow. This would give you a document with id 1. Of course you can change this id to any document in your project.
- Get a design
const design = await liClient.getProjectDesign()
This gets the design used in the project with the API token provided.
A special case (mostly for non-service use cases) is if you want to get a specific globally referenced design. This might not be the design used in your project.
const design = await liClient.getDesign({name: 'living-times', version: '1.0.2'})
- Create a living document
const liSDK = require('@livingdocs/node-sdk')
const livingdoc = liSDK.document.create({content: publication.content, design})
- Render a living document to HTML
livingdoc.render()
- ...or render single components
const liSDK = require('@livingdocs/node-sdk')
const html = liSDK.document.renderComponent(livingdoc.componentTree.first())
Rendering a Document
To sum up, we wrapped the whole procedure in a snippet below:
const liSDK = require('@livingdocs/node-sdk')
const liClient = new liSDK.Client({
url: 'https://server.livingdocs.io',
accessToken: 'my-awesome-token'
})
// fetch document from server
const publication = await liClient.getPublication({documentId: 1})
// fetch design
const design = await liClient.getProjectDesign()
// create document and render it
const livingdoc = liSDK.document.create({content: publication.content, design})
const html = livingdoc.render() // you can also use liSDK.document.render(livingdoc)
// now, do something great with your html... :)
Note: This snippet loads the latest design from your service project and uses our default image service.
Where to go from here
I don't want to use document ids
Livingdocs provides you with a homepage for each project and configurable menus. You can set a homepage and create a menu in the Livingdocs editor (edit.livingdocs.io).
Check out the Client API reference documentation below for the respective methods to fetch the homepage or a menu from Livingdocs.
I need my own design
Currently, you can only use embedded designs in your livingdocs editor. getting started with your own design
Otherwise you can use one of the given design in the editor and adapt the rendering on your side. For the delivery rendering you can have a local copy of our magazine design and adjust the HTML / CSS for the rendering. This means that you will write in the Livingdocs editor in our prebuilt design but render to your own custom design using the SDK.
Check out the Livingdocs magazine example frontend on how to achieve this.
I want to change the output before rendering
The Livingdocs API provides you with our Livingdocs JSON format. The SDK allows you to build a native livingdoc instance out of the JSON response. The livingdoc instance gives you many options to change the output of your rendering, e.g. skipping certain components, set global styling options or change the way images are rendered.
Check out the livingdoc reference documentation for an intro to the livingdoc API.
API Reference Documentation
const liSDK = require('@livingdocs/node-sdk')
Document API
/**
* @function document.create Creates a Livingdoc instance.
* @param options.design: serialised design (required)
* @param options.content: content of a serialised livingdoc (required)
* @param options.config: livingdoc configuration (optional)
* @return Livingdoc
*/
const document = liSDK.document.create({design, content, config})
// Configure an image service (If you define nothing, the default settings below will be used)
// This configures Livindocs' image service (the same that is used on edit.livingdocs.io).
// You can of course also specify your own here or change the parameters for image rendering.
const config = {
imageServices: {
liImageProxy: {
host: 'https://server.livingdocs.io',
preferWebp: true,
backgroundImage: {
maxWidth: 2048
},
srcSet: {
defaultWidth: 1024,
widths: [2048, 1024, 620, 320],
sizes: ['100vw']
}
}
}
}
/**
* @function document.visit Visits components in a ComponentTree.
* @param document: Livingdoc
* @param filter: Object | Function
* @param visitor: (component: Component) => void
* @return Livingdoc
*/
const visitedDocument = liSDK.document.visit(document, filter, visitor)
/**
* @function document.getIncludes Aggregates and groups includes by service name and returns a Map of includes.
* @param document: Livingdoc
* @return { [service: string]: IncludeDirective[] }
*/
const includes = liSDK.document.getIncludes(document)
/**
* @function document.renderComponent Renders a specific component to html.
* @param component: Component
* @return string
*/
const html = liSDK.document.renderComponent(component)
/**
* @function document.render Renders a document to html.
* @param document: Livingdoc
* @return string
*/
const html = liSDK.document.render(document)
Client API
// get an instance of the api client
const liClient = new liSDK.Client({
url: 'http://localhost:3001', // required
accessToken: 'my-awesome-token', // required
proxy: 'http://path.to.proxy', // optional, uses HttpsProxyAgent (https-proxy-agent)
agent: new CustomHttpsAgent() // optional, bring your own (node-fetch compatible) agent, this overrides and ignores the `proxy` config
})
/**
* @function getMenus Fetches menus with optional filters.
* @param filters?: { handle?: string } handle - The given menu handle.
* @return Menu[]
*/
const [menu] = await liClient.getMenus({handle: 'main'})
/**
* @function getDesignVersions Fetches available design versions by name.
* @param options: { name: string } name - The given design name.
* @return {versions: string[]}
*/
const {versions} = await liClient.getDesignVersions({name: 'living-times'})
/**
* @function getProjectDesign Fetches a design by name and version.
* @param options: { version: string } version - Optional property when not the current version should be fetched
* @return Design
*/
const design = await liClient.getProjectDesign({version: '1.0.2'})
/**
* @function getDesign Fetches a design by name and version.
* @param options: { name: string, version: string } - The full design descriptor.
* @return Design
*/
const design = await liClient.getDesign({name: 'living-times', version: '1.0.2'})
/**
* @function getPublications Fetches latest publications with optional filters.
* @param filters?: { homepage?: boolean, limit?: number = 10 }
* @return Publication[]
*/
const [homepagePublication] = await liClient.getPublications({homepage: true, limit: 1})
/**
* @function getPublication Fetches a publication by id.
* @param options: { documentId: number }
* @return Publication
*/
const publication = await liClient.getPublication({documentId})
/**
* @function getMedia Fetches a media objects by id or externalId.
* @param options.id: number Id from the media object
* @param options.ids: array of Ids from the media objects
* @param options.externalId: string Id from the media object from the external system
* @param options.systemName: string name of the external system
* @return Media[]
*/
const media = await liClient.getMedia({id, ids, externalId, systemName})
/**
* @function search Search for publications
* @param options.search: string Search term to perform a full-text search with. For exact word matches use ", e.g. 'search="Ukulele"'
* @param options.categories: string Comma separated list of category ids for which documents should be found. Categories are concatenated with OR. Example: 'sport,fashion'
* @param options.languages: string Comma separated list of languages for which documents should be found. Languages are concatenated with OR. Example: 'en,de'
* @param options.contentTypes: string Comma separated list of content-types for which documents should be found. Content types are concatenated with OR. Example: 'article,author'
* @param options.fields: string Filters which (comma separated) properties are included in the response. Defaults to 'systemdata,metadata,content' (no renditions). Use 'id' if you only want to retrieve the ids of the published documents. Useful (and faster) if you are fully synchronizing your frontend with the publication events.
* @param options.limit: integer A limit for how much published documents to retrieve. Defaults to 10. Max. 100.
* @param options.offset: integer An offset into the query. Useful when getting more than 100 results (pagination)}
* @return Publications
*/
const publications = await liClient.search({search, categories, languages, contentTypes, fields, limit, offset})