Commit f4729fe
fix: Support xlinkHref attribute for SVG image elements (#724)
SVG `<image>` elements only recognized `href` as the image source
attribute, causing errors when using the JSX/React-compatible
`xlinkHref` prop.
```jsx
// This worked
<svg><image href="data:image/..." /></svg>
// This threw "Image source is not provided"
<svg><image xlinkHref="data:image/..." /></svg>
```
## Changes
**src/handler/preprocess.ts**
- Line 125: Check both `href` and `xlinkHref` when resolving image data
from cache
- Lines 159-166: Collect image sources from both `props.href` and
`props.xlinkHref` during preprocessing
**test/image.test.tsx**
- Added test case with `xlinkHref` attribute including `xmlns:xlink`
namespace declaration
The existing `ATTRIBUTE_MAPPING` already handles the `xlinkHref` →
`xlink:href` conversion for SVG output.
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
----
*This section details on the original issue you should resolve*
<issue_title>`xlinkHref` isn't interpreted as source for `<image />` in
SVGs</issue_title>
<issue_description># Bug report
## Description / Observed Behavior
Using namespaced attribute in JSX form like `xlinkHref` instead of
`xlink:href` causes error "Image source is not provided" to be thrown.
## Expected Behavior
Satori should use the JSX/TSX attribute `xlinkHref` as the `<image />`
source, interpreting it the same it does `xlink:href` and `href`.
## Reproduction
[Using `xlink:href`
(works)](https://og-playground.vercel.app/?share=5Vlpb-LIFv0riNGT-sk98b6Q6R7JgFlsY8AbGEUaecM2eF-BVv_3VyaQkPQoetJLPryJpURVp67r3nN8q-pi_-jaieN277vfnKB-iDudojyG7vcfP9p2p-O7geeX952HLoog_3rofn2Em8Ap_V9QJyjS0Dy2-DZ0D0942xkGuWuXQRK3o3YSVlH8NG6GgRdPSzcqzoNuXLr50-CuKspgexwkAI3Pkbwy2IIRJTi59x0SxW6w1SV0CkEuaOkeSrb19cssP38-xH-2jW9F7d1Q_P7QxRHkoXsrxkusDtymnxwAiHSQDhho_66D2yAMwUicxO4VOkRhXADML8v0Hoabprlr8Lsk92AMQRC4dX9reX8Ig3j_t_Zor9eDz8OPd5zjBwxanV9G_yrwa1iNH5Qgrg58e-djE3gHBmiPvMPo3jWgTucIQIK4w2kKewavrhj6GXtyeAvm5znRO_IZKnMzLrZJHoGRPCnN0v1CkJ2L387F1b-f7S-RV3n45bfULMEDjJG_COwvlMJvrIoyT_YusLNC076o84z__qTNdeT_WwD0AwXASPoOpYiXAqAIAG-wd-bfQzoXt51HT2_Txz6UPnVHEk92F_qvk-Kd-aM4CQQ4O74mwtsK4B-6AvA7-vUK-CUr3lmB31EGAdTPnq-58LYExEdKgJB3r5fAL4nx7gqAJHh0fM2FtwUgP1AAAjwIkniVA78kxnsrALaBi-NrKrytAPWRCrze8h-3wZd58d4CgHPg4veSCW_zpz90Cbzc8c_H4Ous-F_4_w0f5h35OO62uLRB7-Lg2u90Agfc9aqceJ6907kMXUpQLQ7KtoJLrB2QqZ9UsRPEHqgBb2-5xoLegk9q3KBPYYHAqsLtnAu6ez93t8DutyAyPfc5pBd5Uthm6H5B7hD0fAGdngiDueBL0P8l7WsR8cloX4uHT0b7WjF8MtrXKuGT0b7WBp-M9rUg-GS0r3XAJ6N9LRf-ebTPc70i_Wr-X-PvPb2DekHgJZzmbuHmtcsWKVBENsHrOWBz-7aqvV4wc8zSvD97h9PY-8MyC5civgZ6fy43iDD2EhZckqL5nOaB1qjt980Ba7Q4kXHcoG0M1v3paj0DrUIF_0Su4dgobc5G7FpSZGTK5gVhU8sWkOOlhvbBXYddUzPGUgPYMlQ0ua9PvD69OVlKIPW56SYnCiVB1tqolqc6t-mxDBtrA3iCZGzquoMRQTclwa8D4sQm0aFY2hu6GvPcgcqi1dDEEBzCGW-2wQIGsnGHQ1FVrlAMwjhx1hjSppRccieQqjiy1QZDKxinXLwUZccSUj3ZREYkoVSOKj5_KHtHM8oEstrGNj2W5GRGxRroTUaHvSaq68HAY5PDit0bOWvO9WCeo25AbOxc9CZkOUg2QwibKDSuwKNZbA2g_WnCi2PInBJZqOVzah6n5iZzYhsZ1TQEkz1K8xWkEOdysDgRUCbpGWkbJFoTzWKwXVj2zFxNS6nUsxAZyjtKZwdyUPQTcsUiWsql0VLLT9l-lvOGOE03Ky3x1gIvrDZxXFqz44kJTxg-HFBbnarWXBVqC3XCFSpDU32Hi4cTdGhKZD9YmzwpIm17UI1HDeUumECaocY8VYAfQHWgB5l-2CfBTthpccir0NpI3Bpbs8reNmJUHfE5C5maMc1N21KSpTLTPX4sNONdaPgz_2T7zBzlKgll5dN8NQx0r-zz_bGOEtvMDGMZE0ra5Sc-k_LT6SHao-5iWO0y046D5MQzDulq481EPDJ1tVKnR21hrufOfophbAVvwtRU2UKfkgK5ghIa3RvQDmm0UWbzFnTwLP1UQGlN01WMGSJJmQrK696aL6o9o5qMSUoRvESZBpv7R8MyiO2WqGlz7K9ndFPFKbpEN-ViFe4g07ei3nqXBX7jCj3YmfCxW-eIWxdWWEgBE9aC2kwYOa6HKxOFVIVwx8ZxGcJJs0VOE0GWrJJx5ioaVViIODHHk3uGH9eYwI2hOhUWh9HJxxbDcenIHjnh6Li0dyiNpkh5rHZbv7DmcSXuNHKmmVieEclKx0Oan0N6rsZ4edxDlRbCqkcqNjq3Iipx8GOR7yKR4rGaX_uIrY0lXEezE4NJOwWqc0FZTMzZQYFgKC4zvOwtsSODwUhxJJR6yDiGF_PzTTbdjQNFZktEXYgyXpLRuhnxlqfMRgl4yCi3GeZC-1wiPcusTKaPvr9Oc0M9CgpIGvo4ZSd6zlHEicw21RgNLcKySF0UcWlFhbAhVROtPm0RfFW7s4W1raN8hAhsmztDWQHpDrI79_JSsCdqf7nMnnNLZvMlQqzyTHK0vaQE0Wpfmdq8UOqVY8uzoHYc-3gIzYDwSaqRHGIjqnk9gsvYYXqivSfNExJqrMHAZYUZxeQx10FuTptVEnvDEofXo1SYkLVdsSg3Oyz2ybbqM0NIOJgTGrzWN_I21wNxuoTdyu0fqRM81Hcxf2AWh3WqCb7J0ds9wQqPWiHcbmQMfIjSG2FE8_aLNdauCX8iZvieS7cTMVkbeY_yhih30j0qnF60sBrG4eERqi0lVZUEe7CWVsNM86QRkMQLDXGpNDJGOVDMJutKBEFu4ZOPDLEBMtqBPV0OysMYGrOHirXJaNFr2r26z8sayeV73vO87-C8uB4jTz_F4aff4t_ajx2gBaCg_vOPh7j7tZuk7Seionv_o3s-ybr37Ted7uP5dek4rlV53futGRbu164bJbtAPabtJ6xtWIFzHkzTfv7hIst1uvdlXrk_v3ZL0wIGvhuGSZPkodP9-R8)
[Using `xlinkHref` (doesn't
work)](https://og-playground.vercel.app/?share=5Vlpb-LIFv0riNGT-sk98YI3Mt0jGTCLbQx4w0aRRt6wDd5XoNX__ZUJJCQ9ip70kg9vYilR1anruvcc36q62D-6duK43fvuNyeoH-JOpyiPofv9x4-23en4buD55X3noYsiyL8eul8f4SZwSv8X1AmKNDSPLb4N3cMT3nZGQe7aZZDE7aidhFUUP42bYeDFs9KNivOgG5du_jS4q4oy2B6HCUDjcySvDLZgRA5O7n2HQLEbbH0JnUSQC1q6h5Jpff0yy8-fD_GfbeNbUXs3FL8_dHsI8tC9FeMlVgduM0gOAEQ6SAcMtH_XwW0QhmAkTmL3Ch2iMC4A5pdleg_DTdPcNb27JPdgDEEQuHV_a6mHQbz_W3O03-_Dh3b48YZz-IBAK_PL4F_FfY2q8YMShNWBb-98bALnwADtE3cY1b_G0-kcAYjjdz2KxJ7BqyuaesaeHN6C-XlO9I54hsrcjIttkkdgJE9Ks3S_4ETn4rdzcfXvZ_tL5FUefvktNUvw_GLkLxz7CyV7N1ZFmSd7F9hZoWlf1HnGf3_S5jry_y0A-oECYAR1h5L4SwFQBIA32Dvz7yOdi9vOo6e36WMfSp-8I_Anuwv910nxzvzRHgEEODu-JsLbCvQ-dAX07qjXK-CXrHhnBX5HaQRQP3u-5sLbEuAfKQFC3L1eAr8kxrsrAJLg0fE1F94WgPhAAXDwIAj8VQ78khjvrQDYBi6Or6nwtgLkRyrwest_3AZf5sV7CwDOgYvfSya8zZ_60CXwcsc_H4Ovs-J_4f83fOh35OO42-LSBr2Lg2u_0wkccNercuJ59k7nMnSpQNU4KNsCLrF2QKZBUsVOEHugBLy95RoLegs-qXGDPoUFAqsKt3Mu6Ka5uwVmvwWR6bnPEb1Ik8I2Q_cLcoeg5wvI9MQXTAVfYv4vWV9riM_F-lo6fC7W13Lhc7G-Vgifi_W1LPhcrK-lwOdifS0APhfra5nwj2N9nusV51fz_xp-_-nN04v4X8Jp7hZuXrtMkQJBJBO8lAM2t--o2uuWmGOW5v3ZOZzG3h-WWbgk_jXQBgupQfiJlzDgEmXVZ1UPtMZtf2AOGaPF8Yxlh21jqA9ma30OWoUC_glswzJR2pyNGF2UJWTG5AVuk6sWkOKVig7AXYddU9PGSgXYKpRVaaBNvQG1OVlyIA7Y2SbHCzlBdHVcSzON3fQZmonVITxFMiZ13eEYp5oS5_QAPzFJdChW9oaqJhx7ILNoPTIxpAf1aG--wQIasnsOi6KKVKEYhLHCvDHETSm6xI4nFGFsKw2GVnCPdHulIDkWn2rJJjIiESVzVPa5Q9k_mlHGE9U2tqmJKCVzMlZBbzo-7FVB0YdDj0kOa2Zv5Iy50IJFjroBvrFzwZsS5TDZjCBsKlM9GR7PY2sI7U9TTphA5gzPQjVfkIs4NTeZE9vIuKYgmOiTqi8jhbCQguUJhzJRywjbINAab5bD7dKy5-Z6VoqlloXISNqRGjOUgmKQEGsGUVM2jVZqfsr285wzhFm6WauJp_M...
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #722
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: shuding <3676859+shuding@users.noreply.github.com>1 parent 7c08d3a commit f4729fe
File tree
3 files changed
+44
-5
lines changed- src/handler
- test
- __image_snapshots__
3 files changed
+44
-5
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
122 | 122 | | |
123 | 123 | | |
124 | 124 | | |
125 | | - | |
| 125 | + | |
126 | 126 | | |
127 | 127 | | |
128 | 128 | | |
| |||
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
159 | | - | |
160 | | - | |
161 | | - | |
162 | | - | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
163 | 166 | | |
164 | 167 | | |
165 | 168 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
138 | 138 | | |
139 | 139 | | |
140 | 140 | | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
141 | 177 | | |
142 | 178 | | |
143 | 179 | | |
| |||
0 commit comments