# Export backlinks on Org export

**URL:** <https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756>\
**Category:** Development\
**Created:** [July 17, 2021, 3:12pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756 "2021-07-17T15:12:09Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![FloppyEggplant](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@FloppyEggplant](https://org-roam.discourse.group/u/FloppyEggplant)\
**Post date:** [July 17, 2021, 3:12pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/1 "2021-07-17T15:12:10Z")

</div>

I’ve been using this to export backlinks when publishing my notes to html, it works with V2.

I hope it will help.

```auto
(defun collect-backlinks-string (backend)
  "Insert backlinks into the end of the org file before parsing it."
  (goto-char (point-max))
  ;; Add a new header for the references
  (insert "\n\n* Referenced in\n")
  (let* ((backlinks (org-roam-backlinks-get (org-roam-node-at-point))))
    (dolist (backlink backlinks)
      (let* ((source-node (org-roam-backlink-source-node backlink))
             (point (org-roam-backlink-point backlink))
             (text (-last-item (org-roam-node-preview (org-roam-node-file source-node)
                                                      point))))
        (insert
         (format "- [[./%s][%s]]\n%s\n"
                 (file-name-nondirectory (org-roam-node-file source-node))
                 (org-roam-node-title source-node)
                 text))))))

(add-hook 'org-export-before-processing-hook 'collect-backlinks-string)

```

The final result will be something like this:

 ![20210717_172400_658_firefox_ieTh2L5Tmm](https://global.discourse-cdn.com/free1/uploads/orgroam/original/1X/93835bf1a3344a48e712fec034a0e4a99254b0aa.png)

---

<div class="post-metadata">

**Author:** ![agnessa](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/agnessa/32/386_2.png) [@agnessa](https://org-roam.discourse.group/u/agnessa)\
**Post date:** [July 19, 2021, 7:31pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/2 "2021-07-19T19:31:51Z")

</div>

Thank you very much!  
But when i try to export any file without org-roam-node, it fails.  
Maybe better add something like

```auto
(when (org-roam-node-at-point)
...
 )

```

?  
I’m not sure how to say it in elisp correct, but this works for me 😃

---

<div class="post-metadata">

**Author:** ![FloppyEggplant](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@FloppyEggplant](https://org-roam.discourse.group/u/FloppyEggplant)\
**Post date:** [July 20, 2021, 5:37pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/3 "2021-07-20T17:37:54Z")

</div>

That is exactly it. Thank you.

Here is the the code:

```auto
(defun collect-backlinks-string (backend)
  "Insert backlinks into the end of the org file before parsing it."
  (when (org-roam-node-at-point)
    (goto-char (point-max))
    ;; Add a new header for the references
    (insert "\n\n* Referenced in\n")
    (let* ((backlinks (org-roam-backlinks-get (org-roam-node-at-point))))
      (dolist (backlink backlinks)
        (let* ((source-node (org-roam-backlink-source-node backlink))
               (point (org-roam-backlink-point backlink))
               (text (-last-item (org-roam-node-preview (org-roam-node-file source-node)
                                                        point))))
          (insert
           (format "- [[./%s][%s]]\n%s\n"
                   (file-name-nondirectory (org-roam-node-file source-node))
                   (org-roam-node-title source-node)
                   text)))))))

(add-hook 'org-export-before-processing-hook 'collect-backlinks-string)

```

---

<div class="post-metadata">

**Author:** ![agnessa](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/agnessa/32/386_2.png) [@agnessa](https://org-roam.discourse.group/u/agnessa)\
**Post date:** [July 28, 2021, 7:50am UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/4 "2021-07-28T07:50:17Z")

</div>

Maybe file-relative-name is better than file-name-nondirectory. I have subfolders in my org-roam folder. 🙂

Wish it is possible to make backlinks list for every org-roam-node in file…

---

<div class="post-metadata">

**Author:** ![FloppyEggplant](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@FloppyEggplant](https://org-roam.discourse.group/u/FloppyEggplant)\
**Post date:** [July 29, 2021, 11:17pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/5 "2021-07-29T23:17:08Z")

</div>

Hey!

I’ve tried to implement a way to take into account files with multiple nodes.

Is it something like this?

An org file:

```auto
:PROPERTIES:
:ID: 114b9147-47c4-4008-9cba-fcb8338f2e98
:END:
#+title: Org-Roam test

Testing stuff with org-roam.

It contains both [[id:foo][Foo]] and [[id:bar][Bar]].

* Foo
:PROPERTIES:
:ID: foo
:END:

Part of [[id:bar][Bar]].

* Bar
:PROPERTIES:
:ID: bar
:END:

Part of [[id:foo][Foo]]

```

The output:

 ![20210730_001314_544_firefox_OQRqPlIn9g](https://global.discourse-cdn.com/free1/uploads/orgroam/original/1X/ce59fc74ef28e1f7efcabab28bdc532b29b7188b.png)

The code:

```auto
(defun collect-backlinks-string (backend)
  (let* ((source-node (org-roam-node-at-point))
         (source-file (org-roam-node-file source-node))
         ;; Sort the nodes by the point to avoid errors when inserting the
         ;; references
         (nodes-in-file (--sort (< (org-roam-node-point it)
                                   (org-roam-node-point other))
                                (-filter (lambda (node)
                                           (s-equals?
                                            (org-roam-node-file node)
                                            source-file))
                                         (org-roam-node-list))))
         ;; Nodes don't store the last position so, get the next node position
         ;; and subtract one character
         (nodes-start-position (-map (lambda (node) (org-roam-node-point node))
                                     nodes-in-file))
         (nodes-end-position (-concat (-map (lambda (next-node-position)
                                              (- next-node-position 1))
                                            (-drop 1 nodes-start-position))
                                      (list (point-max))))
         ;; Keep track of the current-node index
         (current-node 0)
         ;; Keep track of the amount of text added
         (character-count 0))
    (dolist (node nodes-in-file)
      (when (org-roam-backlinks-get node)
        ;; Go to the end of the node and don't forget about previously inserted
        ;; text
        (goto-char (+ (nth current-node nodes-end-position) character-count))
        ;; Add the references as a subtree of the node
        (setq heading (format "\n\n%s References\n\n"
                              (s-repeat (+ (org-roam-node-level node) 1) "*")))
        ;; Also count the new lines (4)
        (setq character-count (+ 4 character-count (string-width heading)))
        (insert heading)
        (dolist (backlink (org-roam-backlinks-get node))
          (let* ((source-node (org-roam-backlink-source-node backlink))
                 (point (org-roam-backlink-point backlink))
                 (text (-last-item (org-roam-node-preview
                                    (org-roam-node-file source-node)
                                    point)))
                 (references (format "- [[./%s][%s]]: %s\n\n"
                                     (file-relative-name (org-roam-node-file source-node))
                                     (org-roam-node-title source-node)
                                     text)))
            ;; Also count the new lines (2)
            (setq character-count (+ 2 character-count (string-width references)))
            (insert references))))
      (setq current-node (+ current-node 1)))))

```

---

<div class="post-metadata">

**Author:** ![agnessa](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/agnessa/32/386_2.png) [@agnessa](https://org-roam.discourse.group/u/agnessa)\
**Post date:** [July 31, 2021, 11:46am UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/6 "2021-07-31T11:46:46Z")

</div>

Thank you!  
It’s really something like this!  
But (i don’t know why) org-roam-node-preview does not works for me now…

---

<div class="post-metadata">

**Author:** ![FloppyEggplant](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@FloppyEggplant](https://org-roam.discourse.group/u/FloppyEggplant)\
**Post date:** [July 31, 2021, 2:23pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/7 "2021-07-31T14:23:24Z")

</div>

Are you using org-roam V2?

Edit: I forgot to add `(when (org-roam-node-at-point)` so here it is the code again:  
Edit 2: You need both `dash.el` and `s.el` packages.

```auto
(defun collect-backlinks-string (backend)
  (when (org-roam-node-at-point)
    (let* ((source-node (org-roam-node-at-point))
           (source-file (org-roam-node-file source-node))
           ;; Sort the nodes by the point to avoid errors when inserting the
           ;; references
           (nodes-in-file (--sort (< (org-roam-node-point it)
                                     (org-roam-node-point other))
                                  (-filter (lambda (node)
                                             (s-equals?
                                              (org-roam-node-file node)
                                              source-file))
                                           (org-roam-node-list))))
           ;; Nodes don't store the last position so, get the next node position
           ;; and subtract one character
           (nodes-start-position (-map (lambda (node) (org-roam-node-point node))
                                       nodes-in-file))
           (nodes-end-position (-concat (-map (lambda (next-node-position)
                                                (- next-node-position 1))
                                              (-drop 1 nodes-start-position))
                                        (list (point-max))))
           ;; Keep track of the current-node index
           (current-node 0)
           ;; Keep track of the amount of text added
           (character-count 0))
      (dolist (node nodes-in-file)
        (when (org-roam-backlinks-get node)
          ;; Go to the end of the node and don't forget about previously inserted
          ;; text
          (goto-char (+ (nth current-node nodes-end-position) character-count))
          ;; Add the references as a subtree of the node
          (setq heading (format "\n\n%s References\n\n"
                                (s-repeat (+ (org-roam-node-level node) 1) "*")))
          ;; Also count the new lines (4)
          (setq character-count (+ 4 character-count (string-width heading)))
          (insert heading)
          (dolist (backlink (org-roam-backlinks-get node))
            (let* ((source-node (org-roam-backlink-source-node backlink))
                   (point (org-roam-backlink-point backlink))
                   (text (-last-item (org-roam-node-preview
                                      (org-roam-node-file source-node)
                                      point)))
                   (references (format "- [[./%s][%s]]: %s\n\n"
                                       (file-relative-name (org-roam-node-file source-node))
                                       (org-roam-node-title source-node)
                                       text)))
              ;; Also count the new lines (2)
              (setq character-count (+ 2 character-count (string-width references)))
              (insert references))))
        (setq current-node (+ current-node 1))))))

```

---

<div class="post-metadata">

**Author:** ![doubleloop](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/doubleloop/32/99_2.png) [@doubleloop](https://org-roam.discourse.group/u/doubleloop)\
**Post date:** [July 31, 2021, 2:43pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/8 "2021-07-31T14:43:21Z")

</div>

Where is `org-roam-node-preview` defined? I get an error when running this code, and indeed I can’t find `org-roam-node-preview` in the source.

---

<div class="post-metadata">

**Author:** ![FloppyEggplant](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@FloppyEggplant](https://org-roam.discourse.group/u/FloppyEggplant)\
**Post date:** [July 31, 2021, 2:46pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/9 "2021-07-31T14:46:01Z")

</div>

By describing the function it says:

```auto
org-roam-node-preview is a Lisp closure in ‘org-roam.el’.

(org-roam-node-preview FILE POINT)

Get preview content for FILE at POINT.

```

---

<div class="post-metadata">

**Author:** ![FloppyEggplant](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@FloppyEggplant](https://org-roam.discourse.group/u/FloppyEggplant)\
**Post date:** [July 31, 2021, 2:53pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/10 "2021-07-31T14:53:42Z")

</div>

I’ve updated my org-roam package and now it doesn’t work. 😃 I will try to fix it.

---

<div class="post-metadata">

**Author:** ![doubleloop](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/doubleloop/32/99_2.png) [@doubleloop](https://org-roam.discourse.group/u/doubleloop)\
**Post date:** [July 31, 2021, 2:56pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/11 "2021-07-31T14:56:47Z")

</div>

I think the name looks to have changed to `org-roam-get-preview` in a recent commit: [(feat)preview: improve org-roam link preview (#1655) · org-roam/org-roam@9c10a3c · GitHub](https://github.com/org-roam/org-roam/commit/9c10a3c04c06d1658a63d44927e385e2d97854d6#diff-2f1e3beb58c04fd0b840c2761afd33f1fddc1b6ef25860d52af87341c3392b51R532)

---

<div class="post-metadata">

**Author:** ![FloppyEggplant](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@FloppyEggplant](https://org-roam.discourse.group/u/FloppyEggplant)\
**Post date:** [July 31, 2021, 2:58pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/12 "2021-07-31T14:58:42Z")

</div>

Yes, the name changed and now it doesn’t return a list, just text. I guess it is fixed now:

```auto
(defun collect-backlinks-string (backend)
  (when (org-roam-node-at-point)
    (let* ((source-node (org-roam-node-at-point))
           (source-file (org-roam-node-file source-node))
           ;; Sort the nodes by the point to avoid errors when inserting the
           ;; references
           (nodes-in-file (--sort (< (org-roam-node-point it)
                                     (org-roam-node-point other))
                                  (-filter (lambda (node)
                                             (s-equals?
                                              (org-roam-node-file node)
                                              source-file))
                                           (org-roam-node-list))))
           ;; Nodes don't store the last position so, get the next node position
           ;; and subtract one character
           (nodes-start-position (-map (lambda (node) (org-roam-node-point node))
                                       nodes-in-file))
           (nodes-end-position (-concat (-map (lambda (next-node-position)
                                                (- next-node-position 1))
                                              (-drop 1 nodes-start-position))
                                        (list (point-max))))
           ;; Keep track of the current-node index
           (current-node 0)
           ;; Keep track of the amount of text added
           (character-count 0))
      (dolist (node nodes-in-file)
        (when (org-roam-backlinks-get node)
          ;; Go to the end of the node and don't forget about previously inserted
          ;; text
          (goto-char (+ (nth current-node nodes-end-position) character-count))
          ;; Add the references as a subtree of the node
          (setq heading (format "\n\n%s References\n\n"
                                (s-repeat (+ (org-roam-node-level node) 1) "*")))
          ;; Also count the new lines (4)
          (setq character-count (+ 4 character-count (string-width heading)))
          (insert heading)
          (dolist (backlink (org-roam-backlinks-get node))
            (let* ((source-node (org-roam-backlink-source-node backlink))
                   (point (org-roam-backlink-point backlink))
                   (text (org-roam-get-preview
                          (org-roam-node-file source-node)
                          point))
                   (references (format "- [[./%s][%s]]: %s\n\n"
                                       (file-relative-name (org-roam-node-file source-node))
                                       (org-roam-node-title source-node)
                                       text)))
              ;; Also count the new lines (2)
              (setq character-count (+ 2 character-count (string-width references)))
              (insert references))))
        (setq current-node (+ current-node 1))))))

```

---

<div class="post-metadata">

**Author:** ![magicscience](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/magicscience/32/915_2.png) [@magicscience](https://org-roam.discourse.group/u/magicscience)\
**Post date:** [August 3, 2021, 4:16pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/13 "2021-08-03T16:16:08Z")

</div>

I’m trying to figure out how to insert a properties drawer on the backlinks node so I can style it with CSS.

when I try:

```auto
        (insert heading)
        (insert ":PROPERTIES:\n:HTML_CONTAINER_CLASS: references\n:END:\n")

```

it does not insert the text correctly, instead it inserts it as formatted text within the node. Any suggestions?

---

<div class="post-metadata">

**Author:** ![FloppyEggplant](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@FloppyEggplant](https://org-roam.discourse.group/u/FloppyEggplant)\
**Post date:** [August 3, 2021, 6:53pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/15 "2021-08-03T18:53:31Z")

</div>

You also need to increase the character count, make it like this bellow the `(insert heading)`:

```lisp
;; Insert properties drawer
(setq properties-drawer ":PROPERTIES:\n:HTML_CONTAINER_CLASS: references\n:END:\n")
;; Count the characters and count the new lines (3)
(setq character-count (+ 3 character-count (string-width properties-drawer)))
(insert properties-drawer)

```

---

<div class="post-metadata">

**Author:** ![magicscience](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/magicscience/32/915_2.png) [@magicscience](https://org-roam.discourse.group/u/magicscience)\
**Post date:** [August 3, 2021, 7:51pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/16 "2021-08-03T19:51:26Z")

</div>

Hm, this is resulting in the same output.

---

<div class="post-metadata">

**Author:** ![FloppyEggplant](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@FloppyEggplant](https://org-roam.discourse.group/u/FloppyEggplant)\
**Post date:** [August 3, 2021, 11:55pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/17 "2021-08-03T23:55:53Z")

</div>

This is what I used. I made 2 changes:

- Removed one `\n` from the heading
- Changed `(setq character-count (+ 4` to `(setq character-count (+ 3` because now it only has 3 new lines.

```lisp
(defun collect-backlinks-string (backend)
  (when (org-roam-node-at-point)
    (let* ((source-node (org-roam-node-at-point))
           (source-file (org-roam-node-file source-node))
           ;; Sort the nodes by the point to avoid errors when inserting the
           ;; references
           (nodes-in-file (--sort (< (org-roam-node-point it)
                                     (org-roam-node-point other))
                                  (-filter (lambda (node)
                                             (s-equals?
                                              (org-roam-node-file node)
                                              source-file))
                                           (org-roam-node-list))))
           ;; Nodes don't store the last position so, get the next node position
           ;; and subtract one character
           (nodes-start-position (-map (lambda (node) (org-roam-node-point node))
                                       nodes-in-file))
           (nodes-end-position (-concat (-map (lambda (next-node-position)
                                                (- next-node-position 1))
                                              (-drop 1 nodes-start-position))
                                        (list (point-max))))
           ;; Keep track of the current-node index
           (current-node 0)
           ;; Keep track of the amount of text added
           (character-count 0))
      (dolist (node nodes-in-file)
        (when (org-roam-backlinks-get node)
          ;; Go to the end of the node and don't forget about previously inserted
          ;; text
          (goto-char (+ (nth current-node nodes-end-position) character-count))
          ;; Add the references as a subtree of the node
          (setq heading (format "\n\n%s References\n"
                                (s-repeat (+ (org-roam-node-level node) 1) "*")))
          ;; Count the characters and count the new lines (4)
          (setq character-count (+ 3 character-count (string-width heading)))
          (insert heading)
          ;; Insert properties drawer
          (setq properties-drawer ":PROPERTIES:\n:HTML_CONTAINER_CLASS: references\n:END:\n")
          ;; Count the characters and count the new lines (3)
          (setq character-count (+ 3 character-count (string-width properties-drawer)))
          (insert properties-drawer)
          (dolist (backlink (org-roam-backlinks-get node))
            (let* ((source-node (org-roam-backlink-source-node backlink))
                   (point (org-roam-backlink-point backlink))
                   (text (org-roam-get-preview
                          (org-roam-node-file source-node)
                          point))
                   (references (format "- [[./%s][%s]]: %s\n\n"
                                       (file-relative-name (org-roam-node-file source-node))
                                       (org-roam-node-title source-node)
                                       text)))
              ;; Also count the new lines (2)
              (setq character-count (+ 2 character-count (string-width references)))
              (insert references))))
        (setq current-node (+ current-node 1))))))

```

---

<div class="post-metadata">

**Author:** ![magicscience](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/magicscience/32/915_2.png) [@magicscience](https://org-roam.discourse.group/u/magicscience)\
**Post date:** [August 4, 2021, 12:07pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/18 "2021-08-04T12:07:11Z")

</div>

Thank you so much! It works.

---

<div class="post-metadata">

**Author:** ![doubleloop](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/doubleloop/32/99_2.png) [@doubleloop](https://org-roam.discourse.group/u/doubleloop)\
**Post date:** [August 8, 2021, 12:56pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/19 "2021-08-08T12:56:02Z")

</div>

Since today I receive this error:

`Symbol's function definition is void: org-roam-get-preview`

Removing the call to `org-roam-get-preview` from `collect-backlinks-string` gets things working again.

Not sure what happened to org-roam-get-preview - maybe related to this PR? - [(feat): globally restructure and refactor the codebase by Wetlize · Pull Request #1724 · org-roam/org-roam · GitHub](https://github.com/org-roam/org-roam/pull/1724) - which does seem to rework a lot of the code.

---

<div class="post-metadata">

**Author:** ![FloppyEggplant](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@FloppyEggplant](https://org-roam.discourse.group/u/FloppyEggplant)\
**Post date:** [August 9, 2021, 9:54am UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/20 "2021-08-09T09:54:15Z")

</div>

The function changed. Now it’s called: `org-roam-preview-get-contents`

I’ve changed the code accordingly and removed new lines from preview, to avoid creating new paragraphs.

```lisp
(defun collect-backlinks-string (backend)
  (when (org-roam-node-at-point)
    (let* ((source-node (org-roam-node-at-point))
           (source-file (org-roam-node-file source-node))
           ;; Sort the nodes by the point to avoid errors when inserting the
           ;; references
           (nodes-in-file (--sort (< (org-roam-node-point it)
                                     (org-roam-node-point other))
                                  (-filter (lambda (node)
                                             (s-equals?
                                              (org-roam-node-file node)
                                              source-file))
                                           (org-roam-node-list))))
           ;; Nodes don't store the last position so, get the next node position
           ;; and subtract one character
           (nodes-start-position (-map (lambda (node) (org-roam-node-point node))
                                       nodes-in-file))
           (nodes-end-position (-concat (-map (lambda (next-node-position)
                                                (- next-node-position 1))
                                              (-drop 1 nodes-start-position))
                                        (list (point-max))))
           ;; Keep track of the current-node index
           (current-node 0)
           ;; Keep track of the amount of text added
           (character-count 0))
      (dolist (node nodes-in-file)
        (when (org-roam-backlinks-get node)
          ;; Go to the end of the node and don't forget about previously inserted
          ;; text
          (goto-char (+ (nth current-node nodes-end-position) character-count))
          ;; Add the references as a subtree of the node
          (setq heading (format "\n\n%s References\n"
                                (s-repeat (+ (org-roam-node-level node) 1) "*")))
          ;; Count the characters and count the new lines (4)
          (setq character-count (+ 3 character-count (string-width heading)))
          (insert heading)
          ;; Insert properties drawer
          (setq properties-drawer ":PROPERTIES:\n:HTML_CONTAINER_CLASS: references\n:END:\n")
          ;; Count the characters and count the new lines (3)
          (setq character-count (+ 3 character-count (string-width properties-drawer)))
          (insert properties-drawer)
          (dolist (backlink (org-roam-backlinks-get node))
            (let* ((source-node (org-roam-backlink-source-node backlink))
                   (point (org-roam-backlink-point backlink))
                   (text (s-replace "\n" " " (org-roam-preview-get-contents
                                           (org-roam-node-file source-node)
                                           point)))
                   (references (format "- [[./%s][%s]]: %s\n\n"
                                       (file-relative-name (org-roam-node-file source-node))
                                       (org-roam-node-title source-node)
                                       text)))
              ;; Also count the new lines (2)
              (setq character-count (+ 2 character-count (string-width references)))
              (insert references))))
        (setq current-node (+ current-node 1))))))

```

---

<div class="post-metadata">

**Author:** ![ketan0](https://avatars.discourse-cdn.com/v4/letter/k/7993a0/32.png) [@ketan0](https://org-roam.discourse.group/u/ketan0)\
**Post date:** [August 19, 2021, 6:16pm UTC](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756/21 "2021-08-19T18:16:41Z")

</div>

Hey, this function is nice, thanks! I’m using it on my website.

I’ve fixed a few bugs in the way it works below. Namely, a node’s end position isn’t necessarily the next node, but rather the next same-level headline (if there is one.) Also, I changed it to sort in decreasing order of the node’s end position (which removes the need for manually counting characters entirely,) and then insert backlinks in that order.

A couple other tweaks I added:

- the outline path, as is displayed in the org-roam-buffer. You can take this out if desired.
- backlinks link directly to the node ID, rather than to the source file.

```lisp
(defun collect-backlinks-string (backend)
  (when (org-roam-node-at-point)
    (let* ((source-node (org-roam-node-at-point))
           (source-file (org-roam-node-file source-node))
           (nodes-in-file (--filter (s-equals? (org-roam-node-file it) source-file)
                                    (org-roam-node-list)))
           (nodes-start-position (-map 'org-roam-node-point nodes-in-file))
           ;; Nodes don't store the last position, so get the next headline position
           ;; and subtract one character (or, if no next headline, get point-max)
           (nodes-end-position (-map (lambda (nodes-start-position)
                                       (goto-char nodes-start-position)
                                       (if (org-before-first-heading-p) ;; file node
                                           (point-max)
                                         (call-interactively
                                          'org-forward-heading-same-level)
                                         (if (> (point) nodes-start-position)
                                             (- (point) 1) ;; successfully found next
                                           (point-max)))) ;; there was no next
                                     nodes-start-position))
           ;; sort in order of decreasing end position
           (nodes-in-file-sorted (->> (-zip nodes-in-file nodes-end-position)
                                      (--sort (> (cdr it) (cdr other))))))
      (dolist (node-and-end nodes-in-file-sorted)
        (-let (((node . end-position) node-and-end))
          (when (org-roam-backlinks-get node)
            (goto-char end-position)
            ;; Add the references as a subtree of the node
            (setq heading (format "\n\n%s References\n"
                                  (s-repeat (+ (org-roam-node-level node) 1) "*")))
            (insert heading)
            (setq properties-drawer ":PROPERTIES:\n:HTML_CONTAINER_CLASS: references\n:END:\n")
            (insert properties-drawer)
            (dolist (backlink (org-roam-backlinks-get node))
              (let* ((source-node (org-roam-backlink-source-node backlink))
                     (properties (org-roam-backlink-properties backlink))
                     (outline (when-let ((outline (plist-get properties :outline)))
                                  (mapconcat #'org-link-display-format outline " > ")))
                     (point (org-roam-backlink-point backlink))
                     (text (s-replace "\n" " " (org-roam-preview-get-contents
                                                (org-roam-node-file source-node)
                                                point)))
                     (reference (format "%s [[id:%s][%s]]\n%s\n%s\n\n"
                                        (s-repeat (+ (org-roam-node-level node) 2) "*")
                                        (org-roam-node-id source-node)
                                        (org-roam-node-title source-node)
                                        (if outline (format "%s (/%s/)"
                                        (s-repeat (+ (org-roam-node-level node) 3) "*") outline) "")
                                        text)))
                (insert reference)))))))))

```

[Next page](https://org-roam.discourse.group/t/export-backlinks-on-org-export/1756.md?page=2)
