From 7b7eb371c8f9273c2e833a1d28d1cf2be3144e6d Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Mon, 16 Feb 2026 04:16:47 +0000 Subject: [PATCH] fix(bundler): place inline script at end of body for standalone HTML Move the inline ", .{js_chunk.unique_key}, 0)); + defer allocator.free(script); + try endTag.before(script, true); + } + } + fn getHeadTags(this: *@This(), allocator: std.mem.Allocator) bun.BoundedArray([]const u8, 2) { var array: bun.BoundedArray([]const u8, 2) = .{}; if (this.compile_to_standalone_html) { - // In standalone HTML mode, inline CSS and JS directly into the HTML + // In standalone HTML mode, only put CSS in ; JS goes before if (this.chunk.getCSSChunkForHTML(this.chunks)) |css_chunk| { - // Emit - the unique key will be replaced with actual CSS content const style_tag = bun.handleOom(std.fmt.allocPrintSentinel(allocator, "", .{css_chunk.unique_key}, 0)); array.appendAssumeCapacity(style_tag); } - if (this.chunk.getJSChunkForHTML(this.chunks)) |js_chunk| { - // Emit - the unique key will be replaced with actual JS content - const script = bun.handleOom(std.fmt.allocPrintSentinel(allocator, "", .{js_chunk.unique_key}, 0)); - array.appendAssumeCapacity(script); - } } else { // Put CSS before JS to reduce chances of flash of unstyled content if (this.chunk.getCSSChunkForHTML(this.chunks)) |css_chunk| { @@ -197,7 +206,12 @@ fn generateCompileResultForHTMLChunkImpl(worker: *ThreadPool.Worker, c: *LinkerC fn endBodyTagHandler(end: *lol.EndTag, opaque_this: ?*anyopaque) callconv(.c) lol.Directive { const this: *@This() = @ptrCast(@alignCast(opaque_this.?)); if (this.linker.dev_server == null) { - this.addHeadTags(end) catch return .stop; + if (this.compile_to_standalone_html) { + // In standalone mode, insert JS before so DOM is available + this.addBodyTags(end) catch return .stop; + } else { + this.addHeadTags(end) catch return .stop; + } } else { this.end_tag_indices.body = @intCast(this.output.items.len); } @@ -207,7 +221,13 @@ fn generateCompileResultForHTMLChunkImpl(worker: *ThreadPool.Worker, c: *LinkerC fn endHtmlTagHandler(end: *lol.EndTag, opaque_this: ?*anyopaque) callconv(.c) lol.Directive { const this: *@This() = @ptrCast(@alignCast(opaque_this.?)); if (this.linker.dev_server == null) { - this.addHeadTags(end) catch return .stop; + if (this.compile_to_standalone_html) { + // Fallback: if no was found, insert both CSS and JS before + this.addHeadTags(end) catch return .stop; + this.addBodyTags(end) catch return .stop; + } else { + this.addHeadTags(end) catch return .stop; + } } else { this.end_tag_indices.html = @intCast(this.output.items.len); } @@ -237,6 +257,7 @@ fn generateCompileResultForHTMLChunkImpl(worker: *ThreadPool.Worker, c: *LinkerC .head = null, }, .added_head_tags = false, + .added_body_script = false, }; HTMLScanner.HTMLProcessor(HTMLLoader, true).run(