# Joplin note sharing tool

**URL:** <https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480>\
**Category:** Apps\
**Created:** [30 December 2020 14:50 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480 "2020-12-30T14:50:30Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [30 December 2020 14:50 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/1 "2020-12-30T14:50:31Z")

</div>

# joplin-blog

> [中文](https://joplin-utils.rxliuli.com/zh/joplin-blog/)

## Introduction

CLI tool to publish Joplin notes as a static website, currently supports both blog/wiki forms, framework supports hexo/vuepress/docsify.

- blog
  - [hexo](https://joplin-utils.rxliuli.com/blog/hexo/)
  - [vuepress](https://joplin-utils.rxliuli.com/blog/vuepress/)
  - [jeykll](https://joplin-utils.rxliuli.com/blog/jeykll/)

- wiki
  - [vuepress](https://joplin-utils.rxliuli.com/wiki/vuepress/)
  - [docsify](https://joplin-utils.rxliuli.com/wiki/docsify/)

![blog demo](https://raw.githubusercontent.com/rxliuli/joplin-utils/master/apps/joplin-blog/docs/blog.png)  
 ![wiki demo](https://raw.githubusercontent.com/rxliuli/joplin-utils/master/apps/joplin-blog/docs/wiki.png)

## Requirements

- Install nodejs and npm(installed by default)
- Knowledge of command line
- Understanding VSCode

## Use

1. Navigate to the relevant directory at the command line
2. Add dependencies `npm i -D joplin-blog`.
3. add a configuration file `.joplin-blog.json` (see [configuration](#configuration) for details)
4. add an npm script file `"gen": "joplin-blog blog"` (if you want to generate a wiki then `"gen": "joplin-blog wiki"`)
5. Run the command `npm run gen`
6. Then you can see that the relevant directory already contains the notes and attached resources

> Please add two files _.joplin-blog.json_ and _.joplin-cache.json_ to the _.gitignore_ ignore file, the former contains sensitive information `token`, the latter is automatically generated.

## examples

The supported frameworks have examples in the examples directory, which you can clone locally to see.

- [blog hexo](https://github.com/rxliuli/joplin-utils/tree/master/examples/blog-hexo-example)
- [blog vuepress](https://github.com/rxliuli/joplin-utils/tree/master/examples/blog-vuepress-example)
- [blog jeykll](https://github.com/rxliuli/joplin-utils/tree/master/examples/blog-jeykll-example)
- [wiki vuepress](https://github.com/rxliuli/joplin-utils/tree/master/examples/wiki-vuepress-example)
- [wiki docsify](https://github.com/rxliuli/joplin-utils/tree/master/examples/wiki-docsify-example)

## Configuration

public

| Configuration | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | `hexo/vuepress/docsify` | yes | type of integrated blog |
| `rootPath` | `string` | no | hexo/vuepress directory, default is `.` |
| `token` | `string` | yes | token for joplin web clipper |
| `baseUrl` | `string` | no | base path of joplin web clipper, default is `http://localhost:41184` |
| `tag` | `string` | yes | joplin's blog tag |

hexo

| configuration | type | description |
| --- | --- | --- |
| `stickyTopIdList` | `string[]` | Topped note id (only valid under [fluid topic](https://github.com/fluid-dev/hexo-theme-fluid/blob/master/README_en.md)) |

I've shared over 190 notes with this tool, [blog address (Chinese)](https://blog.rxliuli.com/)

## FAQ

### What does token/port refer to and where can I find it?

You can usually see it in **Tools \> Options \> Web Clipper**

![joplin web clipper](https://img.rxliuli.com/20210316092547.png)

### Why did the note id of the exported blog, wiki change?

Some possible reasons are

- Export jex and then import jex, all notes here are created operations, refer to: [https://discourse.joplinapp.org/t/when-will-joplin-modify-the-id-of-the-note/17806](https://discourse.joplinapp.org/t/when-will-joplin-modify-the-id-of-the-note/17806)
- Notes conflict when syncing

### nodejs 18 is not fully compatible

Currently, some ArchLinux users report that they cannot use joplin-blog, but after troubleshooting, they found that replacing nodejs 16 lts works, please use nodejs 16 lts first.

Related issue: [https://github.com/rxliuli/joplin-utils/issues/45](https://github.com/rxliuli/joplin-utils/issues/45)

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [30 December 2020 15:04 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/2 "2020-12-30T15:04:33Z")

</div>

@thwaller @ser May be interested

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [17 March 2021 01:49 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/3 "2021-03-17T01:49:37Z")

</div>

# CHANGELOG

## v0.1.6

- test: modified the configuration of the hexo example, delete the custom stickyTopIdList and permalink
- revert: "hexo intergrated compatibility markdown", fix: [求助：markdown 图片在post page 页面不加载 · Issue #7 · rxliuli/joplin-blog · GitHub](https://github.com/rxliuli/joplin-blog/issues/7)
- docs: Update the description of joplinProfilePath in README

## v0.1.5

- Fix README update being overwritten error

## v0.1.4

- Fix [exporting error](https://github.com/rxliuli/joplin-blog/issues/5)
- Fix [mistake correct](https://github.com/rxliuli/joplin-blog/issues/6)

## v0.1.3

- HexoIntegrated compatibility markdown images render path, ref: [hexo intergrated compatibility markdown by ozhiwei · Pull Request #4 · rxliuli/joplin-blog · GitHub](https://github.com/rxliuli/joplin-blog/pull/4)

## v0.1.2

- Fixed passing tag from config instead of hard-coded to blog

## v0.1.1

- Fix the problem that the `\r` in the title is not cleared when exporting hexo blog

## v0.1.1

- Basic export function realization, currently supports hexovuepress

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [17 April 2021 22:06 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/4 "2021-04-17T22:06:03Z")

</div>

Currently cli has been completely refactored, and v0.2.0 has been released, with major changes

- Completely refactor the code
- Realize the internationalization of output information
- Implement a more friendly cli

 ![image](https://canada1.discourse-cdn.com/flex028/uploads/cozic/original/2X/c/c55e5a1c01eef3a4afd5adf476639d3d60f4c77a.png)

## recent goals

- Achieve a blog project associated with joplin from scratch
- Allow users to complete export, packaging, and deployment operations without touching the underlying dependency  
framework
- Implement a wiki generator
- Support docsify
- Support vuepress
- Integrated into the joplin plugin to provide a certain degree of visual interface

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [16 May 2021 09:33 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/5 "2021-05-16T09:33:19Z")

</div>

Release 0.3.0, support generating a wiki website with sidebar structure from Joplin, the general effect is as follows

 ![image](https://canada1.discourse-cdn.com/flex028/uploads/cozic/original/3X/8/f/8f3c8200e2c3369b3324af9a051e3ce5a8c17c5b.jpeg)

> Example project: [joplin-blog/examples/wiki-vuepress-example/package.json at joplin-blog@0.3.0 · rxliuli/joplin-blog · GitHub](https://github.com/rxliuli/joplin-blog/blob/joplin-blog@0.3.0/examples/wiki-vuepress-example/package.json)

There are still some internationalization and details that have not been completed. I will fill up later, but I will not continue to develop the GUI version of joplin-blog (the previously developed parts, including generation, command packaging, and deployment have all been deleted), This is really troublesome, especially when I develop this tool but don't use it.

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [23 June 2021 03:00 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/6 "2021-06-23T03:00:33Z")

</div>

Changes since 0.3.0 =\> 0.4.0

- feat(joplin-blog): Use worker\_threads to parse and convert markdown to avoid blocking the main thread
- fix(joplin-blog): Fix the error that asyncLimit will print numbers when running commands
- refactor(joplin-blog): Expose more functions in `src/index` to facilitate third-party calls
- fix (joplin-blog): fix missing international files
- fix (joplin-blog): unified modification example generation command imp =\> gen
- fix (joplin-blog): Fix the redundant space in the docsify sidebar configuration generated by Joplin
- fix (blog-hexo-example): fix the bug that hexo cannot be deployed to the site subdirectory

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [30 July 2021 05:33 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/7 "2021-07-30T05:33:19Z")

</div>

Publish 0.5.1

This is an important upgrade. The use of the cache function has increased the generation speed, and when there is no modification, it has been reduced from 20+s to 2+s. Optimization is based on two premises

- The number of modified notes should be much smaller than the unmodified ones
- Attachment resources will not be modified basically

> npm link: [joplin-blog - npm](https://www.npmjs.com/package/joplin-blog)

Specific change information

- feat(joplin-blog): add internationalization configuration of cache command
- feat(joplin-blog): implement resource caching, add cached commands
- refactor(joplin-blog): refactor the key of the internationalization string to use a more meaningful naming scheme
- feat(joplin-blog): implements caching functionality
- refactor(joplin-blog): refactor the functions previously written to notes and resources into fixed directories for easy calculation of cache locations
- fix(joplin-blog): fix warning that comlink/dist/umd/node-adapter is not used as an external dependency when packaging
- fix(joplin-blog): fix bug with i18next-util reference
- docs(joplin-blog): update the deployment location of joplin-blog, and update the documentation
- docs(joplin-blog): add json schema for configuration files
- refactor(joplin-blog): utility @liuli-util/i18next-util in the joplin-blog project
- chore(root): update the version of joplin-blog in the example module
- chore(joplin-blog): update rollup-plugin-worker-threads

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [31 July 2021 14:41 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/8 "2021-07-31T14:41:32Z")

</div>

Publish 0.6.0

- feat(joplin-blog): Add a subcommand clean under the blog/wiki command to delete cached configuration files, notes and attachment resource directories

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [3 October 2021 07:34 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/9 "2021-10-03T07:34:30Z")

</div>

Release 0.7.0

The main update is to support generating files for jeykll blog. The example project is at [https://github.com/rxliuli/joplin-utils/tree/master/examples/blog-jeykll-example](https://github.com/rxliuli/joplin-utils/tree/master/examples/blog-jeykll-example), the online example you can view: \<https: [//joplin-utils.rxliuli.com/blog/jeykll/](https://joplin-utils.rxliuli.com/blog/jeykll/)\>

changelog

- fix: Fix an issue where the integration object created when the generated blog type is jekyll is incorrect
- fix: add missing development dependency builtin-modules
- feat: integrate jekyll into cli commands
- feat: support jekyll framework
- chore: update liuli-cli to improve packaging performance (48s =\> 23s)
- chore: add yarn plugin interactive-tools, upgrade liuli-cli
- chore(root): merge conflicts
- fix(joplin-blog): use diff only once to get deleted, modified and added notes and resources
- chore(root): replace lerna with yarn 2

The original demand comes from: [https://discourse.joplinapp.org/t/plugin-generate-static-blog-website-and-publish-to-github-pages/20630/11?u=rxliuli](https://discourse.joplinapp.org/t/plugin-generate-static-blog-website-and-publish-to-github-pages/20630/11)

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [3 April 2022 10:06 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/10 "2022-04-03T10:06:40Z")

</div>

Release 0.7.2

- fix: Modify bin.js =\> bin.cjs to force the use of commonjs to avoid errors in higher versions of nodejs
- fix: fix generated markdown file ordered list error, ref: [https://github.com/rxliuli/joplin-utils/issues/36](https://github.com/rxliuli/joplin-utils/issues/36)

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [15 April 2022 15:58 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/11 "2022-04-15T15:58:44Z")

</div>

Release 0.8.0

- feat: set the target of typescript to esnext, which is only compatible with the latest version of nodejs lts by default
- feat: remove the dependency on the local joplin resource location, download the resource to the local through the clipper api
- refactor: updated joplin-api sdk, no longer depends on axios

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [16 April 2022 16:19 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/12 "2022-04-16T16:19:53Z")

</div>

Release 0.8.1

The main change is to update the joplin-api dependency to support the use of the joplin clipper api running remotely, and also to reduce the bundle size by replacing the dependency

- refactor: replace luxon =\> dayjs
- refactor: update joplin-api sdk
- feat: update to use latest joplin-api sdk, update port =\> baseUrl

> **[Release joplin-blog@0.8.1 · rxliuli/joplin-utils](https://github.com/rxliuli/joplin-utils/releases/tag/joplin-blog@0.8.1)**
>
> refactor: replace luxon =\> dayjs
> refactor: update joplin-api sdk
> feat: update to use latest joplin-api sdk, update port =\> baseUrl

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [6 September 2022 11:08 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/13 "2022-09-06T11:08:30Z")

</div>

Release 0.9.0

The main change is to support more flexible requirements programmatically, including modifying the meta metadata of each markdown file when it is generated, such as adding an author field, which looks like this

```nohighlight
import {
  Application,
  ApplicationConfig,
  BlogHexoIntegrated,
  BlogHexoIntegratedConfig,
  GeneratorEvents,
  ProcessInfo,
} from 'joplin-blog'
import { CommonNote, CommonTag, CommonResource } from 'joplin-blog/dist/model/CommonNote'
import _config from './.joplin-blog.json'

class GeneratorEventsImpl implements GeneratorEvents {
  copyResources(options: ProcessInfo): void {
    console.log(`${options.rate}/${options.all} Reading note attachments and tags: `, options.title)
  }

  parseAndWriteNotes(options: ProcessInfo): void {
    console.log(
      `${options.rate}/${options.all} Parsing Joplin internal links and attached resources in notes: ${options.title}`,
      options.title,
    )
  }

  readNoteAttachmentsAndTags(options: ProcessInfo): void {
    console.log(`${options.rate}/${options.all} Writing note: ${options.title}`, options.title)
  }

  writeNote(options: ProcessInfo): void {
    console.log(`${options.rate}/${options.all} Processing resource: ${options.title}`)
  }
}

class BlogIntegrated extends BlogHexoIntegrated {
  meta(note: CommonNote & { tags: CommonTag[]; resources: CommonResource[] }) {
    return {
      ...super.meta(note),
      author: 'rxliuli'
    }
  }
}

async function main() {
  const config: ApplicationConfig & BlogHexoIntegratedConfig = {
    ...(_config as ApplicationConfig),
    rootPath: __dirname,
  }
  const generatorEvents = new GeneratorEventsImpl()
  await new Application(config, new BlogIntegrated(config))
    .gen()
    .on('readNoteAttachmentsAndTags', generatorEvents.readNoteAttachmentsAndTags)
    .on('parseAndWriteNotes', generatorEvents.parseAndWriteNotes)
    .on('writeNote', generatorEvents.writeNote)
    .on('copyResources', generatorEvents.copyResources)
}

main()

```

The configuration of .joplin-blog.json looks like

```json
{
  "type": "hexo",
  "token": "",
  "tag": "blog"
}

```

changelog

- feat: support adding custom meta when generating pages, ref: [https://github.com/rxliuli/joplin-utils/issues/55](https://github.com/rxliuli/joplin-utils/issues/55)
- fix: fix missing dependencies, remove unnecessary wallaby configuration
- chore: update @liuli-util/async
- docs: update readme, add nodejs 18 incompatibility note
- chore: update joplin-api
- fix: fix bin.cjs not adding #/usr/bin/env node error
- fix: fix a bug where headers in body are not properly removed

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [2 October 2022 16:47 UTC](https://discourse.joplinapp.org/t/joplin-note-sharing-tool/13480/14 "2022-10-02T16:47:35Z")

</div>

joplin-blog released 0.9.4, which contains a very big performance improvement, now it only takes a few seconds to generate the files needed by the website without caching

no cache

```nohighlight
$ time pnpm gen

real 0m4.838s
user 0m0.015s
sys 0m0.076s

```

with cache

```nohighlight
$ time pnpm gen

real 0m2.093s
user 0m0.000s
sys 0m0.075s

```

generated content

```nohighlight
github.com/AlDanial/cloc v 1.94 T=0.91 s (281.5 files/s, 57807.1 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Markdown 228 10568 0 37902
SVG 24 0 7 4163
HTML 5 6 0 128
-------------------------------------------------------------------------------
SUM: 257 10574 7 42193
-------------------------------------------------------------------------------

```

changelog

- migrated to esm module
- Refactored the code to converge dependencies
- Do not bundle all dependent code in bundle
- no longer using workers (low performance as markdown parsing)

ref: [https://www.npmjs.com/package/joplin-blog](https://www.npmjs.com/package/joplin-blog)
