Logseq as "org-roam mobile"

Background

What is it that every Org-mode knowledge worker needs but doesn't have? A WYSIWYG Org editor for mobile.

You see, for the use-case of plain notetaking, all the traditional Org apps like Beorg, PlainOrg, MobileOrg and Organice fall flat: they seem to be oriented towards TODO tasks & scheduling & reminders, and they presume that if you write prose or poetry, you will only capture to an inbox file and sort it out later on your desktop. Polish a hundred files of prose? No way, no one does that! Right? (None of your users do, I'm sure, but there's a reason for that)

So, they hide the free-form text editor several screen taps away, and it lacks all UX.

I'm not looking for TODO task integration, I just need a smooth writing experience like the iPhone's built-in Notes app. Nothing more. Because I have to use apps like iOS Notes instead of Beorg & co, all my notes on-the-go end up siloed in that app. I'm tired of mentally tracking the disconnect between "my notes on the phone" and "my real Org notes on the laptop".

Enter Logseq! If you've briefly tried Logseq mobile in the past, you might be surprised to hear that it has a reasonable editing experience, more so than the other platforms I mentioned.

However, Logseq appears confusing on first try. It uses non-standard UX and lacks some discoverability, and the tutorials I found by Googling failed to cut through to the relevant facts for someone like you and me.

The gotchas I wish someone'd told me

Disclaimer: not all these problems will apply to you. I would have fewer problems writing "traditional" large Org files, but I write according to org-roam conventions, i.e. many small "zettelkasten".

OK, let's get started!

Formatting norms

Starting out, you'll note Logseq seems to put absolutely everything in a list. These lists are a lie. What you think is a list item is what they call a "block", which translates to Org jargon as a subtree.

This looks familiar only so long as you don't really have paragraph-text under your Org headings. If you do, you can hide the leading bullets by switching to "Document mode", and the result may feel more familiar.

To make sense of the Logseq UI, know that it's designed around the assumption you'll use subtrees extensively. This flies in the face of how I and many others write in Org-roam: many of my files have zero subtrees.


The above leads us to a small gotcha: Logseq expects headings. If the first logical line of text is not a heading, Logseq will still interpret it as a heading. So there's this odd leading bullet out of nowhere before the first paragraph. Think nothing of it; it's only cosmetic. Again, Document mode should hide it (sometimes it bugs and does not, so turn it off and back on).

(In fact, the bullet-out-of-nowhere happens even if the first paragraph is actually a set of properties such as #+TITLE, but you can hide them by putting into config.edn the line :block-hidden-properties #{:title}. Then you'll instead have an empty line at the top, which is there because of the file-level ID in your Org-roam files. Again, just cosmetic. A blank line isn't so bad.)


On the mobile app, we have buttons for manipulating subtrees: all the polished stuff you'd expect, like indenting and outdenting them, and moving them. These work only on subtrees! In fact, TODO state ends up being visually rendered as a checkbox when you're not editing, which tells you something about how they intend subtrees to be used.

You don't need to adopt the writing style presumed by Logseq, but it basically works like this: imagine that your initfiles include (setq org-startup-folded 'showeverything), and you eliminate the settings for the faces org-level-1 thru org-level-8 so that headings look just like the default face. Then you write lots and lots of headings, as if they were plain lists, and forget about regular plain lists. That's the expected style in a nutshell.

Bear in mind, Logseq will render conventional Org documents fairly sanely, so it works fine as a viewer. The discomfort arises when you want to edit inside Logseq and still stick to your non-Logseq norms: then you need to always keep in mind what you're doing to the underlying file. But I expect this becomes second nature after some time.

Collaboration

An extra conundrum arises when you want to use Logseq to collaborate on documents with a partner. In that case, I suggest giving up and formatting those specific documents in the Logseq way to make your partners more comfortable in the app, if they aren't technical people.

To edit such Logseq-ified documents in Emacs, I make myself comfortable with this buffer-local mode:

(defvar-local my-logseq-cookies nil)
(define-minor-mode my-logseq-mode
  "De-fontify Org headings."
  :group 'org
  (when (featurep 'org)
    (let ((headline-faces '(org-level-1
                            org-level-2
                            org-level-3
                            org-level-4
                            org-level-5
                            org-level-6
                            org-level-7
                            org-level-8)))
      (if my-logseq-mode
          (dolist (face headline-faces)
            (push (face-remap-add-relative face 'default) my-logseq-cookies))
        (while my-logseq-cookies
          (face-remap-remove-relative (pop my-logseq-cookies)))))))

Also: Never write tables or plain lists in these documents, they're hard to edit from inside Logseq mobile.

For the rest of this post, my tips assume you aren't doing this, but formatting org-mode files like you'd normally do: with headings-as-headings (as short as possible), NOT headings-as-paragraphs (potentially very long).

Syncing

If any of your devices is an iPhone/iPad, you'll have to use Logseq Sync, an experimental beta feature.

As an experimental beta feature, Logseq Sync isn't a poster child of sync resolution (as of [2023-04-09 Sun]) – it isn't made for the purpose of simultaneous collaboration, nor is it prepared to find that someone has edited the files in Emacs while Logseq was not running.

(You'd think it would be at least on par with the simple disk file-based syncers like Syncthing and Nextcloud, but it isn't yet.)

So stay safe:

  • Try to edit only one person at a time, and ensure the sync is complete before beginning to edit.
  • Ensure the sync is complete (cloud icon turns green) before closing the app.
  • Before editing in Emacs, launch Logseq so it can sync in the background.
  • Use only one graph in Logseq, because as of [2023-04-09 Sun] it only syncs the currently opened graph, leaving the others unsynced!
  • When anything feels off, or you know that one of you has created/renamed files, use the "Re-index" action.
  • Donate so Logseq Sync gets better.
  • Know how to recover.
    • Logseq provides a revision history, but my problem has been more that it refused to accept edits I made in Emacs while Logseq was offline, so those edits never enter the revision history to begin with. Not much use of a revision history then…
    • Automated Git commits (done by Emacs, not Logseq) can act as a nice safety net. I have them anyway because it makes sense for org-roam notes, and it just takes a small initfile snippet to set up: raw.githubusercontent.com/meedstrom/doom.d/master/71-auto-commit.el
    • Note that the above snippet of mine amends all commits made within the same day, so your edits can be still forgotten if you don't realize Logseq rolled-back your files before you go on to make more edits.

      For me not a problem because auto-revert-mode + goggles-mode show clearly that Logseq rolled back my changes, and then the first thing I'll do is type C-/ to undo (if the buffer was already open) or open up Magit and type k for "discard".

      Anyway, enable the builtin Emacs backup system for safety. On that note, have you seen backup-walker?

In case of export to HTML

If you ever want to export a Logseq-formatted document, Logseq has its own exporter you can use for the one-off use cases.

But if like me, you're doing a pipeline of publishing your entire org-roam directory to a blog, you'll probably choose to stick with the Org exporter. What I do is tag the Logseq-ified files with the file-level tag :logseq:, I give such pages an extra CSS class (raw.githubusercontent.com/meedstrom/doom.d/master/61-publishing.el), so I can write custom CSS rules for them.

Document title problems

Problems:

  1. Logseq works fine without any #+TITLE property, but org-roam needs it.
    • A workaround can be to avoid file-level titles and IDs, and only use subtrees and subtree IDs. Both programs can parse such files just fine.
  2. When you create a page inside Logseq, there won't be a #+TITLE or file-level ID — nor can you control the resulting filename format if that matters to you.

Solution: Just don't make a habit of creating pages in Logseq. When you do, fix the file with Emacs later.

More problems:

  1. When you rename a page in Logseq, it will change the filename. It will not change the #+TITLE property!
    • (The darnedest thing is that it'll add a meaningless :title: property inside the file-level property drawer, which must be a bug because org-mode generally doesn't do anything with this property. Probably an oversight by a mainly-Markdown dev. May be the same issue behind the phantom blank line mentioned earlier.)
  2. Renaming in Logseq also changes the filename, which you may not want.

Solution: don't ever rename pages through the UI, do it by tapping on the property drawer at the top of the page to reveal the #+TITLE and editing that. Yes, you'll have to instruct your partner to do this, or you can just fix all the renames later.

More problems:

  1. When you link a page in Logseq by typing square brackets … the on-disk result isn't an org-id id: link.

Newlines

There are two keys that can create a newline, with different effects (just like you have RET, M-RET, M-S-RET in org-mode). On the desktop Logseq app, they're Return and Shift+Return. The first is context-aware and very happy to create new subtrees, so as an org-roam writer you probably want to just avoid Return.

Before you ding the devs for this oddness, these keys are actually in line with convention for modern UI, in a way. Think of what you do in a chat app: if you want to send your chat message, you press Return. If you just want to make a newline without sending, you press Shift+Return. It's the same here.

However, on mobile it's the inverse. Chat apps have a dedicated Send button, so the onscreen keyboard's return key just prints a newline. In Logseq Mobile, it's instead the onscreen keyboard's return key that has magic behavior. The equivalent to polite old Shift+Return is present as a button just above the screen keyboard.

Plain checkbox lists

How to insert checkboxes in the app?

First, there's a long-unfixed bug (github.com/logseq/logseq/issues/3147). You'll have more success writing list bullets as + instead of the more conventional -.

+ [ ] i am a list item

Second, you have to type the first list-item manually, but after that, just enter newlines to autocreate more items.

Third, there are no indent/outdent commands for lists (only for subtrees). To make a sub-list, you have to manually prepend two spaces, but after that, you can once again enter newlines to autocreate new items at the correct indentation.

(It's telling that this is still better UX than any other Org app I've tried…)

Fourth, you'll sometimes see list items not being rendered as such. This isn't necessarily a bug, it can be that you tried to write a list item as the first text of a subtree… meaning you actually wrote a heading that happens to start with a dash character! Think logically about the underlying Org file.

Slash-commands

For someone who only uses the mobile app (and not desktop Logseq), this feature is so non-discoverable I'm impressed. In short, you should know there's a bunch of commands you can call by typing a slash character (/) anywhere (yes, on mobile too), and some others by typing an opening angle bracket (<). You can even add new commands in config.edn. Do with that info what you will.

Logseq keeps re-creating mysterious files called "Favorites", "Contents" and "Card"

As far as I can tell, there's no way to stop this. Maybe by adding to config.edn this line?

:hidden ["/page/contents.org" "/page/favorites.org"]

Anyway, you can just cope with this by using them. They're magic files;

  • what goes in contents.org also appears in the right-hand sidebar, and far as I can tell, it's meant as a sort of master index like Wikipedia's List of lists of lists;
  • what goes in favorites.org appears in the left-hand sidebar as a favorites section.

AHHH too many empty journal files!

Don't worry, these pages are imaginary. They don't exist as disk files until you write something in them.

The odd thing is that you enter the journal every time the app starts up, even if the journal is disabled…!

So it's not enough to put in config.edn this line:

:feature/enable-journals? false

You'll also want to set a homepage so it won't open the journals. Like this:

:default-home {:page "Contents"}

Other gotchas good to know

While org-id can accept any string as the ID, Logseq requires you to follow the UUID format. It's a bug they're working on.

More bugs

  1. It creates a page named "date" backlinking to all my files that have a #+date:. Might be intentional?
  2. When I import a big Org file called Someday/Maybe, logseq creates a lot of empty pages named e.g. Maybe, and home, home/kept, home/kept/roam etc (these are fragments of my directory tree). Maybe files just mustn't have slashes in the title?
  3. (Logseq Sync) It's hard to delete files from multiple devices, they keep popping back if one device still has the file. Worse, changes sometimes get undone. It could be an issue of differing system clocks?

    I suspect many issues would go away if Logseq simply read from the filesystem every time, but it seems to work with a cached image of what it thinks is on the filesystem (much like org-roam has its DB, which is also sometimes out of sync, but it only uses it for lookups when you're about to insert a link so causes no real problem). As of [2023-04-11 Tue] it seems I essentially have to tap "Re-index" for good measure every time I enter the app, although even then, some changes get reverted.

Summary cheatsheet

Some necessary config.edn lines

:preferred-format "Org"
:preferred-workflow :todo

Some optional config.edn lines, if you like the journal

:journal/page-title-format "yyyy-MM-dd"

or, to disable journals…

:feature/enable-journals? false
:default-home {:page "Contents"}

Usage

  1. Type newlines via Shift+Return, i.e. use that button above the touchscreen keyboard
  2. Type lists with the plus sign
  3. Stick with the regular org-id UUID format

If collaborating, instruct your partner:

  1. to ensure the sync completes before they edit
  2. to rename by editing #+TITLE manually

Conclusion

For all the little problems we have with Logseq, they're good problems to have. I'm glad this app exists. Thanks devs!

What links here

  • 2023-04-08
Created (15 months ago)
Updated (6 months ago)