I am trying to stream in my nextjs front end and am getting random spaces where there shouldn't be

I’m having a lot of issues when streaming to my nextjs front end. If I do nothing all the letters come in all run together with no spaces. Chat GPT says this is normal and gave me some code to fix it on the client, and it mostly works but I am seeing spaces between random letters sometimes in words. Seems like this should be easier, I’m not sure what I’m doing wrong. Is there a library or something I’m missinig to handle this better? I’m streaming from a modal back end like so:

for chunk in llm.stream(prompt):
                if chunk.content:
                    yield f"data: {chunk.content}\n\n"
        except Exception as e:
            yield f"data: ERROR: {str(e)}\n\n"
and in my front end I have:

response = await fetch(“/api/ask”, {
method: “POST”,
headers: { “Content-Type”: “application/json” },
body: JSON.stringify({ question: submittedQuestion }),
});

      if (!response.ok) throw new Error(`HTTP error ${response.status}`);

      setQuestion("");
      let lastChar = "";
      const reader = response.body?.getReader();
      const decoder = new TextDecoder("utf-8");

      let buffer = "";
      let tempChunk = "";
      while (true) {
        //@ts-ignore
        const { done, value } = await reader.read();
        if (done) {
          htmlString = cleanUpPunctuationSpacing(htmlString);
          setAnswer(htmlString);
          // Generate audio if dictation is enabled
          let audioSrc: string | undefined = undefined;
          if (audioEnabled) {
            setIsGeneratingAudio(true);
            audioSrc = await generateAudio(htmlString, voice);
            setIsGeneratingAudio(false);
          }
          // Update the last message with the answer and audio
          setMessages((prev) => {
            const newMessages = [...prev];
            newMessages[newMessages.length - 1] = {
              ...newMessages[newMessages.length - 1],
              answer: htmlString,
              html: htmlString,
              isLoading: false,
              audioSrc,
            };
            return newMessages;
          });
          break;
        }

        const chunk = decoder.decode(value, { stream: true });
        buffer += chunk;

        const lines = buffer.split("\n\n");

        for (let i = 0; i < lines.length - 1; i++) {
          const line = lines[i].trim();
          if (line.startsWith("data:")) {
            const content = line.replace(/^data:\s*/, "");
            console.log("💬 Incoming chunk:", content);
            if (content.startsWith("ERROR:")) {
              setErrorMsg(content.replace("ERROR: ", ""));
              setIsLoading(false);
              setSubmittedQuestion("");
              return;
            }

            setIsLoading(false);

            const spaced = appendChunkWithSmartSpacing(htmlString, content);
            htmlString = spaced;
            setHtml(spaced);

            // Update the last message immediately with each chunk

Seems like this should be easier. What am I missing?