diff --git a/CHANGELOG.md b/CHANGELOG.md
index 17e5c96..666bc9a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
 - [#53]: Let `clojure-ts-mode` derive from `clojure-mode` for Emacs 30+.
 - [#42]: Fix imenu support for definitions with metadata.
 - [#42]: Fix font locking of definitions with metadata
+- [#42]: Fix indentation of definitions with metadata
 
 ## 0.2.2 (2024-02-16)
 
diff --git a/clojure-ts-mode.el b/clojure-ts-mode.el
index a538b67..09247cc 100644
--- a/clojure-ts-mode.el
+++ b/clojure-ts-mode.el
@@ -737,19 +737,20 @@ https://github.com/weavejester/cljfmt/blob/fb26b22f569724b05c93eb2502592dfc2de89
          (or (clojure-ts--symbol-node-p first-child)
              (clojure-ts--keyword-node-p first-child)))))
 
-(defun clojure-ts--match-expression-in-body (_node parent _bol)
+(defun clojure-ts--match-expression-in-body (node parent _bol)
   "Match NODE if it is an expression used in a body argument.
 PARENT is expected to be a list literal.
 See `treesit-simple-indent-rules'."
   (and
    (clojure-ts--list-node-p parent)
-   (let ((first-child (treesit-node-child parent 0 t)))
+   (let ((first-child (clojure-ts--node-child-skip-metadata parent 0)))
      (and
       (not
        (clojure-ts--symbol-matches-p
         ;; Symbols starting with this are false positives
         (rx line-start (or "default" "deflate" "defer"))
         first-child))
+      (not (clojure-ts--match-with-metadata node))
       (clojure-ts--symbol-matches-p
        clojure-ts--symbols-with-body-expressions-regexp
        first-child)))))
@@ -821,6 +822,12 @@ forms like deftype, defrecord, reify, proxy, etc."
            (clojure-ts--match-fn-docstring parent)
            (clojure-ts--match-method-docstring parent))))
 
+(defun clojure-ts--match-with-metadata (node &optional _parent _bol)
+  "Match NODE when it has metadata."
+  (let ((prev-sibling (treesit-node-prev-sibling node)))
+    (and prev-sibling
+         (clojure-ts--metadata-node-p prev-sibling))))
+
 (defun clojure-ts--semantic-indent-rules ()
   "Return a list of indentation rules for `treesit-simple-indent-rules'."
   `((clojure
@@ -833,6 +840,7 @@ forms like deftype, defrecord, reify, proxy, etc."
      (clojure-ts--match-threading-macro-arg prev-sibling 0)
      ;; https://guide.clojure.style/#vertically-align-fn-args
      (clojure-ts--match-function-call-arg (nth-sibling 2 nil) 0)
+     (clojure-ts--match-with-metadata parent 0)
      ;; Literal Sequences
      ((parent-is "list_lit") parent 1) ;; https://guide.clojure.style/#one-space-indent
      ((parent-is "vec_lit") parent 1) ;; https://guide.clojure.style/#bindings-alignment
diff --git a/test/clojure-ts-mode-indentation-test.el b/test/clojure-ts-mode-indentation-test.el
new file mode 100644
index 0000000..e4d73a6
--- /dev/null
+++ b/test/clojure-ts-mode-indentation-test.el
@@ -0,0 +1,138 @@
+;;; clojure-ts-mode-indentation-test.el --- Clojure TS Mode: indentation test suite  -*- lexical-binding: t; -*-
+
+;; Copyright © 2022-2024 Danny Freeman
+
+;; This file is not part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The unit test suite of Clojure TS Mode
+
+(require 'clojure-ts-mode)
+(require 'cl-lib)
+(require 'buttercup)
+(require 's nil t)               ;Don't burp if it's missing during compilation.
+
+
+(defmacro when-indenting-with-point-it (description before after)
+  "Return a buttercup spec.
+
+Check whether the swift indentation command will correctly change the buffer.
+Will also check whether point is moved to the expected position.
+
+BEFORE is the buffer string before indenting, where a pipe (|) represents
+point.
+
+AFTER is the expected buffer string after indenting, where a pipe (|)
+represents the expected position of point.
+
+DESCRIPTION is a string with the description of the spec."
+  (declare (indent 1))
+  `(it ,description
+    (let* ((after ,after)
+           (expected-cursor-pos (1+ (clojure-ts--s-index-of "|" after)))
+           (expected-state (delete ?| after)))
+      (with-clojure-ts-buffer ,before
+        (goto-char (point-min))
+        (search-forward "|")
+        (delete-char -1)
+        (font-lock-ensure)
+        (indent-according-to-mode)
+        (expect (buffer-string) :to-equal expected-state)
+        (expect (point) :to-equal expected-cursor-pos)))))
+
+
+
+;; Backtracking indent
+(defmacro when-indenting-it (description &rest forms)
+  "Return a buttercup spec.
+
+Check that all FORMS correspond to properly indented sexps.
+
+DESCRIPTION is a string with the description of the spec."
+  (declare (indent 1))
+  `(it ,description
+     (progn
+       ,@(mapcar (lambda (form)
+                   `(with-temp-buffer
+                      (clojure-ts-mode)
+                      (insert "\n" ,form);,(replace-regexp-in-string "\n +" "\n " form))
+                      (indent-region (point-min) (point-max))
+                      (expect (buffer-string) :to-equal ,(concat "\n" form))))
+                 forms))))
+
+
+;; Provide font locking for easier test editing.
+
+(font-lock-add-keywords
+ 'emacs-lisp-mode
+ `((,(rx "(" (group "when-indenting-with-point-it") eow)
+    (1 font-lock-keyword-face))
+   (,(rx "("
+         (group "when-indenting-with-point-it") (+ space)
+         (group bow (+ (not space)) eow)
+         )
+    (1 font-lock-keyword-face)
+    (2 font-lock-function-name-face))))
+
+
+(describe "indentation"
+  (it "should not hang on end of buffer"
+    (with-clojure-ts-buffer "(let [a b]"
+      (goto-char (point-max))
+      (expect
+       (with-timeout (2)
+         (newline-and-indent)
+         t))))
+
+  (when-indenting-with-point-it "should have no indentation at top level"
+    "|x"
+
+    "|x")
+
+  (when-indenting-it "should handle non-symbol at start"
+    "
+{\"1\" 2
+ *3 4}")
+
+  (when-indenting-it "should have no indentation at top level lists with metadata"
+    "
+^{:foo true}
+(def b 2)")
+
+  (when-indenting-it "should have no indentation at top level vectors with metadata"
+    "
+^{:foo true}
+[1 2]")
+
+  (when-indenting-it "should have no indentation at top level maps with metadata"
+    "
+^{:foo true}
+{:a 1}")
+
+  (when-indenting-it "should have no indentation with metadata inside comment"
+    "
+(comment
+  ^{:a 1}
+  (def a 2))")
+
+  (when-indenting-it "should have params, docstring and body correctly indented in presence of metadata"
+    "
+^{:foo true}
+(defn c
+  \"hello\"
+  [_foo]
+  (+ 1 1))"))
diff --git a/test/samples/indentation.clj b/test/samples/indentation.clj
index a5fe041..2996229 100644
--- a/test/samples/indentation.clj
+++ b/test/samples/indentation.clj
@@ -118,3 +118,28 @@
           ([a] a)
           ([a b]
            b))})
+
+
+^:foo
+(def a 1)
+
+^{:foo true}
+(def b 2)
+
+^{:foo true}
+[1 2]
+
+(comment
+  ^{:a 1}
+  (def a 2))
+
+(defn hinted
+  (^String [])
+  (^java.util.List
+   [a & args]))
+
+^{:foo true}
+(defn c
+  "hello"
+  [_foo]
+  (+ 1 1))
diff --git a/test/test-helper.el b/test/test-helper.el
index 38bce56..3866003 100644
--- a/test/test-helper.el
+++ b/test/test-helper.el
@@ -46,4 +46,13 @@ and point left there."
                              (delete-char -1)
                              ,@body)))
 
+(defun clojure-ts--s-index-of (needle s &optional ignore-case)
+  "Returns first index of NEEDLE in S, or nil.
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences."
+  (declare (pure t) (side-effect-free t))
+  (let ((case-fold-search ignore-case))
+    (string-match-p (regexp-quote needle) s)))
+
 ;;; test-helper.el ends here