Added PNG export feature for preview screenshots#138
Conversation
|
Someone is attempting to deploy a commit to the debmallya-03's projects Team on Vercel. A member of the Team first needs to authorize it. |
✅ Deploy Preview for webifynet ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a “Export Image” capability to capture the Live Preview as a PNG using html2canvas, with a small adjustment to global security headers and inclusion of a few local helper scripts.
Changes:
- Add
html2canvasdependency and implement PNG export from the preview UI. - Update
next.config.tsheaders route matcher to exclude/_nextpaths. - Add three Python scripts intended to patch a local
app/page.tsxfile.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Adds html2canvas dependency used for image export. |
| next.config.ts | Adjusts the headers matcher to skip /_next assets. |
| app/page.tsx | Implements exportImage() and adds an “Export Image” button in the preview header. |
| fix_syntax.py | Adds a local one-off script that edits app/page.tsx via absolute path. |
| fix_syntax2.py | Adds a local one-off script that edits app/page.tsx via absolute path and hard-coded line ranges. |
| fix_syntax3.py | Adds a local one-off script that edits app/page.tsx via absolute path and pattern matching. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -1,4 +1,4 @@ | |||
| "use client" | |||
| "use client" | |||
| const tempIframe = document.createElement("iframe") | ||
| tempIframe.style.cssText = `position:fixed;left:-9999px;top:0;width:${width}px;height:${height}px;border:none;` | ||
| document.body.appendChild(tempIframe) | ||
| tempIframe.srcdoc = combinedHtml |
| try { | ||
| const { default: html2canvas } = await import("html2canvas") |
| document.body.removeChild(tempIframe) | ||
| toast.dismiss(loadingToast) |
| } catch (err) { | ||
| console.error("Export image error:", err) | ||
| toast.dismiss(loadingToast) | ||
| toast.error("Export failed", { | ||
| description: err instanceof Error ? err.message : "Unknown error", | ||
| }) | ||
| } |
| with open(r'c:\Users\lishi\webify\Webify\app\page.tsx', 'r', encoding='utf-8') as f: | ||
| lines = f.readlines() | ||
|
|
||
| # Find the problematic area - lines around 1123-1134 (0-indexed: 1122-1133) | ||
| # Looking for the pattern: "} catch {}" followed by "} catch {" | ||
| i = 0 | ||
| fixes = 0 | ||
| while i < len(lines): | ||
| # Find " } catch {}" followed by empty line and " } catch {" | ||
| stripped = lines[i].rstrip() | ||
| if stripped == ' } catch {}' and i + 2 < len(lines): | ||
| next_non_empty = i + 1 | ||
| while next_non_empty < len(lines) and lines[next_non_empty].strip() == '': | ||
| next_non_empty += 1 | ||
| if next_non_empty < len(lines) and '} catch {' in lines[next_non_empty]: | ||
| # Found duplicate - remove from i+1 to end of duplicate catch block | ||
| # Find the closing } of the duplicate catch | ||
| end = next_non_empty + 1 | ||
| brace_count = 1 if '{' in lines[next_non_empty] and '}' not in lines[next_non_empty].split('{', 1)[1] else 0 | ||
| if lines[next_non_empty].rstrip().endswith('{'): | ||
| # Multi-line catch block | ||
| while end < len(lines) and brace_count > 0: | ||
| if '{' in lines[end]: | ||
| brace_count += lines[end].count('{') | ||
| if '}' in lines[end]: | ||
| brace_count -= lines[end].count('}') | ||
| end += 1 | ||
| else: | ||
| # Single line like "} catch {\n }\n" | ||
| end = next_non_empty + 1 | ||
| while end < len(lines) and lines[end].strip() != '': | ||
| if lines[end].strip() == '}': | ||
| end += 1 | ||
| break | ||
| end += 1 | ||
|
|
||
| print(f"Removing duplicate catch at lines {i+2}-{end} (1-indexed)") | ||
| print(f" Content: {''.join(lines[i+1:end])}") | ||
| # Remove the blank line(s) and duplicate catch block | ||
| del lines[i+1:end] | ||
| fixes += 1 | ||
| continue | ||
| i += 1 | ||
|
|
||
| if fixes > 0: | ||
| with open(r'c:\Users\lishi\webify\Webify\app\page.tsx', 'w', encoding='utf-8') as f: | ||
| f.writelines(lines) | ||
| print(f'\nFixed {fixes} duplicate catch blocks') | ||
| else: | ||
| print('No fixes needed') |
| with open(r'c:\Users\lishi\webify\Webify\app\page.tsx', 'r', encoding='utf-8') as f: | ||
| lines = f.readlines() | ||
|
|
||
| # Remove lines 1123-1125 (0-indexed: 1122-1124) - the duplicate "} catch { }" | ||
| # And lines 1132-1135 (0-indexed: 1131-1134) - the duplicate "} catch { // corrupted... }" | ||
|
|
||
| # Work backwards to avoid index shifting | ||
| # Second duplicate: lines 1133-1135 (1-indexed), 0-indexed 1132-1134 | ||
| del lines[1132:1135] | ||
|
|
||
| # First duplicate: lines 1123-1125 (1-indexed), 0-indexed 1122-1124 | ||
| del lines[1122:1125] | ||
|
|
||
| with open(r'c:\Users\lishi\webify\Webify\app\page.tsx', 'w', encoding='utf-8') as f: | ||
| f.writelines(lines) | ||
|
|
||
| print('Fixed') | ||
|
|
||
| # Verify | ||
| with open(r'c:\Users\lishi\webify\Webify\app\page.tsx', 'r', encoding='utf-8') as f: | ||
| lines = f.readlines() | ||
| print('Lines 1115-1135:') | ||
| for i in range(1114, 1135): | ||
| print(f'{i+1}: {lines[i]}', end='') |
| with open(r'c:\Users\lishi\webify\Webify\app\page.tsx', 'r', encoding='utf-8') as f: | ||
| lines = f.readlines() | ||
|
|
||
| # Remove lines 1123-1125 (0-indexed: 1122-1124) - the duplicate "} catch { }" | ||
| # And lines 1132-1135 (0-indexed: 1131-1134) - the duplicate "} catch { // corrupted... }" | ||
|
|
||
| # Work backwards to avoid index shifting | ||
| # Second duplicate: lines 1133-1135 (1-indexed), 0-indexed 1132-1134 | ||
| del lines[1132:1135] | ||
|
|
||
| # First duplicate: lines 1123-1125 (1-indexed), 0-indexed 1122-1124 | ||
| del lines[1122:1125] | ||
|
|
||
| with open(r'c:\Users\lishi\webify\Webify\app\page.tsx', 'w', encoding='utf-8') as f: | ||
| f.writelines(lines) | ||
|
|
||
| print('Fixed') | ||
|
|
||
| # Verify | ||
| with open(r'c:\Users\lishi\webify\Webify\app\page.tsx', 'r', encoding='utf-8') as f: | ||
| lines = f.readlines() | ||
| print('Lines 1115-1135:') | ||
| for i in range(1114, 1135): | ||
| print(f'{i+1}: {lines[i]}', end='') |
| @@ -0,0 +1,36 @@ | |||
| with open(r'c:\Users\lishi\webify\Webify\app\page.tsx', 'r', encoding='utf-8') as f: | |||
|
Hi @Debmallya-03 , I’ve resolved the merge conflicts and updated the PR. Sorry for the inconvenience. Could you please review and merge it when you have a chance? Thank you! |
Implemented an Export Image feature that allows users to capture and download the current preview as a PNG screenshot directly from the preview section.
Changes Made
Added an Export Image option in the preview header
Implemented screenshot capture for the currently rendered preview/UI component
Enabled automatic download of the captured preview as a .png file
Recording.2026-05-26.172544.mp4
CLOSES #107