rememberHighlightedCode

fun rememberHighlightedCode(code: String, language: String, theme: HighlightTheme = LocalHighlightTheme.current, onHighlightComplete: (HighlightResult) -> Unit? = null, onError: (HighlightException) -> Unit? = null): State<AnnotatedString?>

Pre-highlights code and remembers the resulting AnnotatedString.

Returns null while highlighting is in progress or if highlighting failed. Callers should always render a plain-text fallback when the state is null.

Re-runs automatically when code, language, or theme changes.

Usage

@Composable
fun CodeSnippet(code: String, language: String) {
val highlighted by rememberHighlightedCode(code, language)

// highlighted is null while loading or if highlighting failed;
// fall back to plain text in that case
Text(
text = highlighted ?: AnnotatedString(code),
style = TextStyle(fontFamily = FontFamily.Monospace),
)
}

Theme creation

Built-in themes are precompiled and need no android.content.Context:

val theme = remember { HighlightTheme.tomorrow() }
val highlighted by rememberHighlightedCode(code, "kotlin", theme)

For custom CSS-backed themes, wrap creation in remember so CSS parsing does not repeat on every recomposition. Or use the built-in convenience functions which handle this internally:

val highlighted by rememberHighlightedCode(code, "kotlin", rememberTomorrowTheme())

For light/dark toggling without re-highlighting, prefer rememberHighlightedCodeBothThemes.

Return

A State holding the highlighted AnnotatedString, or null while loading / on error.

Parameters

code

The source code to highlight.

language

The Highlight.js language identifier (e.g. "python", "kotlin").

theme

The theme to apply. Defaults to LocalHighlightTheme.

onHighlightComplete

Optional callback invoked with a HighlightResult when highlighting succeeds. Fires after the State is updated. Not called on failure.

onError

Optional callback invoked with the HighlightException when highlighting fails. Use this to log failures, show a snackbar, or record analytics. The plain-text fallback is always displayed regardless of whether this callback is set - it is purely observational. Use rememberUpdatedState semantics: the latest lambda is always called without restarting the effect. The HighlightException subtypes give you typed error info:

val highlighted by rememberHighlightedCode(
code = myCode,
language = userInput,
onError = { error ->
Log.w("Highlight", "Failed to highlight: ${error.message}")
},
)