diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8beb83e..432e36d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,8 @@
 * `Input` values that are invalid are now also stored in `History`
 * Resolve some issues with cursor positioning in `Input` when using `utf-8` characters
 * Correct page is shown when default selected option is not on the first page for `Select`
+* Fix panic in `FuzzySelect` when using non-ASCII characters
+* Add handling of `Delete` key for `FuzzySelect`
 
 ### Breaking
 
@@ -27,6 +29,7 @@
 * Prompt interaction functions now take `self` instead of `&self`
 * Prompt interaction functions and other operations now return `dialouger::Result` instead of `std::io::Result`
 * Rename `Validator` to `InputValidator`
+* The trait method `Theme::format_fuzzy_select_prompt()` now takes a byte position instead of a cursor position in order to support UTF-8.
 
 ## 0.10.4
 
diff --git a/src/prompts/fuzzy_select.rs b/src/prompts/fuzzy_select.rs
index 28dc68c..706cd5e 100644
--- a/src/prompts/fuzzy_select.rs
+++ b/src/prompts/fuzzy_select.rs
@@ -195,7 +195,7 @@ impl FuzzySelect<'_> {
 
     fn _interact_on(self, term: &Term, allow_quit: bool) -> Result<Option<usize>> {
         // Place cursor at the end of the search term
-        let mut position = self.initial_text.len();
+        let mut cursor = self.initial_text.chars().count();
         let mut search_term = self.initial_text.to_owned();
 
         let mut render = TermThemeRenderer::new(term, self.theme);
@@ -224,8 +224,15 @@ impl FuzzySelect<'_> {
         let mut vim_mode = false;
 
         loop {
+            let mut byte_indices = search_term
+                .char_indices()
+                .map(|(index, _)| index)
+                .collect::<Vec<_>>();
+
+            byte_indices.push(search_term.len());
+
             render.clear()?;
-            render.fuzzy_select_prompt(self.prompt.as_str(), &search_term, position)?;
+            render.fuzzy_select_prompt(self.prompt.as_str(), &search_term, byte_indices[cursor])?;
 
             // Maps all items to a tuple of item and its match score.
             let mut filtered_list = self
@@ -304,14 +311,14 @@ impl FuzzySelect<'_> {
                     }
                     term.flush()?;
                 }
-                (Key::ArrowLeft, _, _) | (Key::Char('h'), _, true) if position > 0 => {
-                    position -= 1;
+                (Key::ArrowLeft, _, _) | (Key::Char('h'), _, true) if cursor > 0 => {
+                    cursor -= 1;
                     term.flush()?;
                 }
                 (Key::ArrowRight, _, _) | (Key::Char('l'), _, true)
-                    if position < search_term.len() =>
+                    if cursor < byte_indices.len() - 1 =>
                 {
-                    position += 1;
+                    cursor += 1;
                     term.flush()?;
                 }
                 (Key::Enter, Some(sel), _) if !filtered_list.is_empty() => {
@@ -331,14 +338,18 @@ impl FuzzySelect<'_> {
                     term.show_cursor()?;
                     return Ok(sel_string_pos_in_items);
                 }
-                (Key::Backspace, _, _) if position > 0 => {
-                    position -= 1;
-                    search_term.remove(position);
+                (Key::Backspace, _, _) if cursor > 0 => {
+                    cursor -= 1;
+                    search_term.remove(byte_indices[cursor]);
+                    term.flush()?;
+                }
+                (Key::Del, _, _) if cursor < byte_indices.len() - 1 => {
+                    search_term.remove(byte_indices[cursor]);
                     term.flush()?;
                 }
                 (Key::Char(chr), _, _) if !chr.is_ascii_control() => {
-                    search_term.insert(position, chr);
-                    position += 1;
+                    search_term.insert(byte_indices[cursor], chr);
+                    cursor += 1;
                     term.flush()?;
                     sel = Some(0);
                     starting_row = 0;
diff --git a/src/theme/colorful.rs b/src/theme/colorful.rs
index 53de10e..9756950 100644
--- a/src/theme/colorful.rs
+++ b/src/theme/colorful.rs
@@ -403,31 +403,24 @@ impl Theme for ColorfulTheme {
         f: &mut dyn fmt::Write,
         prompt: &str,
         search_term: &str,
-        cursor_pos: usize,
+        bytes_pos: usize,
     ) -> fmt::Result {
         if !prompt.is_empty() {
             write!(
                 f,
                 "{} {} ",
-                &self.prompt_prefix,
+                self.prompt_prefix,
                 self.prompt_style.apply_to(prompt)
             )?;
         }
 
-        if cursor_pos < search_term.len() {
-            let st_head = search_term[0..cursor_pos].to_string();
-            let st_tail = search_term[cursor_pos + 1..search_term.len()].to_string();
-            let st_cursor = self
-                .fuzzy_cursor_style
-                .apply_to(search_term.to_string().chars().nth(cursor_pos).unwrap());
-            write!(
-                f,
-                "{} {}{}{}",
-                &self.prompt_suffix, st_head, st_cursor, st_tail
-            )
-        } else {
-            let cursor = self.fuzzy_cursor_style.apply_to(" ");
-            write!(f, "{} {}{}", &self.prompt_suffix, search_term, cursor)
-        }
+        let (st_head, remaining) = search_term.split_at(bytes_pos);
+        let mut chars = remaining.chars();
+        let chr = chars.next().unwrap_or(' ');
+        let st_cursor = self.fuzzy_cursor_style.apply_to(chr);
+        let st_tail = chars.as_str();
+
+        let prompt_suffix = &self.prompt_suffix;
+        write!(f, "{prompt_suffix} {st_head}{st_cursor}{st_tail}",)
     }
 }
diff --git a/src/theme/mod.rs b/src/theme/mod.rs
index 2d661f0..d22001c 100644
--- a/src/theme/mod.rs
+++ b/src/theme/mod.rs
@@ -253,20 +253,13 @@ pub trait Theme {
         f: &mut dyn fmt::Write,
         prompt: &str,
         search_term: &str,
-        cursor_pos: usize,
+        bytes_pos: usize,
     ) -> fmt::Result {
         if !prompt.is_empty() {
-            write!(f, "{} ", prompt)?;
+            write!(f, "{prompt} ")?;
         }
 
-        if cursor_pos < search_term.len() {
-            let st_head = search_term[0..cursor_pos].to_string();
-            let st_tail = search_term[cursor_pos..search_term.len()].to_string();
-            let st_cursor = "|".to_string();
-            write!(f, "{}{}{}", st_head, st_cursor, st_tail)
-        } else {
-            let cursor = "|".to_string();
-            write!(f, "{}{}", search_term, cursor)
-        }
+        let (st_head, st_tail) = search_term.split_at(bytes_pos);
+        write!(f, "{st_head}|{st_tail}")
     }
 }