diff --git a/collects/scribble/base-render.ss b/collects/scribble/base-render.ss
index 491b581f..e9d41647 100644
--- a/collects/scribble/base-render.ss
+++ b/collects/scribble/base-render.ss
@@ -387,6 +387,8 @@
              (render-content (strip-aux (car v)) part ri)
              (render-content (list "[missing]") part ri)))]
         [(element? i)
+         (when (render-element? i)
+           ((render-element-render i) this part ri))
          (render-content (element-content i) part ri)]
         [(delayed-element? i)
          (render-content (delayed-element-content i ri) part ri)]
diff --git a/collects/scribble/html-render.ss b/collects/scribble/html-render.ss
index aaaf6a2d..4b8e0650 100644
--- a/collects/scribble/html-render.ss
+++ b/collects/scribble/html-render.ss
@@ -816,7 +816,10 @@
                      ,@(if (null? (element-content e))
                          `(,(format "~s" (tag-key (link-element-tag e) ri)))
                          (render-plain-element e part ri))))))))]
-        [else (render-plain-element e part ri)]))
+        [else 
+         (when (render-element? e)
+           ((render-element-render e) this part ri))
+         (render-plain-element e part ri)]))
 
     (define/private (render-plain-element e part ri)
       (let* ([raw-style (flatten-style (and (element? e) (element-style e)))]
diff --git a/collects/scribble/latex-render.ss b/collects/scribble/latex-render.ss
index b9ce918d..26542cbf 100644
--- a/collects/scribble/latex-render.ss
+++ b/collects/scribble/latex-render.ss
@@ -91,6 +91,8 @@
       null)
 
     (define/override (render-element e part ri)
+      (when (render-element? e)
+        ((render-element-render e) this part ri))
       (let ([part-label? (and (link-element? e)
                               (pair? (link-element-tag e))
                               (eq? 'part (car (link-element-tag e)))
diff --git a/collects/scribble/struct.ss b/collects/scribble/struct.ss
index dcad3625..a6ae47e1 100644
--- a/collects/scribble/struct.ss
+++ b/collects/scribble/struct.ss
@@ -309,7 +309,9 @@
   prop:serializable
   (make-serialize-info
    (lambda (d)
-     (vector (collect-element-collect d)))
+     (vector (make-element
+              (element-style d)
+              (element-content d))))
    #'deserialize-collect-element
    #f
    (or (current-load-relative-directory) (current-directory))))
@@ -325,6 +327,29 @@
 
 ;; ----------------------------------------
 
+(define-struct (render-element element) (render)
+  #:property
+  prop:serializable
+  (make-serialize-info
+   (lambda (d)
+     (vector (make-element
+              (element-style d)
+              (element-content d))))
+   #'deserialize-render-element
+   #f
+   (or (current-load-relative-directory) (current-directory))))
+
+(provide deserialize-render-element)
+(define deserialize-render-element
+  (make-deserialize-info values values))
+
+(provide/contract
+ [struct render-element ([style any/c]
+                         [content list?]
+                         [render (any/c part? resolve-info? . -> . any)])])
+
+;; ----------------------------------------
+
 (define-struct generated-tag ()
   #:property
   prop:serializable
diff --git a/collects/scribblings/scribble/struct.scrbl b/collects/scribblings/scribble/struct.scrbl
index cd0031f7..6a83cb43 100644
--- a/collects/scribblings/scribble/struct.scrbl
+++ b/collects/scribblings/scribble/struct.scrbl
@@ -155,6 +155,11 @@ A @deftech{block} is either a @techlink{table}, an
                          the browser, or for rendering to other
                          formats.}
 
+                   @item{An instance of @scheme[render-element] has a
+                         procedure that is called in the
+                         @techlink{render pass} of document
+                         processing.}
+
              }}}}
 
        @item{A @deftech{delayed block} is an instance of
@@ -546,6 +551,16 @@ element remains intact (i.e., it is not replaced) by either the
 
 }
 
+@defstruct[(render-element element) ([render (any/c part? resolve-info? . -> . any)])]{
+
+Like @scheme[delayed-element], but the @scheme[render] procedure is called
+during the @techlink{render pass}.
+
+If a @scheme[render-element] instance is serialized (such as when
+saving collected info), it is reduced to a @scheme[element] instance.
+
+}
+
 @defstruct[with-attributes ([style any/c]
                             [assoc (listof (cons/c symbol? string?))])]{