PDFShift GST Invoice PDF Missing Rupee Symbol: How to Fix It
Fix a missing ₹ in a PDFShift GST invoice by checking the source character, font glyph coverage, and font loading before conversion.
If a PDFShift-generated GST invoice is missing the Indian rupee sign (₹), check these three things in order: the character in your HTML, whether the font file has a glyph for it, and whether that font finished loading before PDFShift converted the page. The rupee sign is Unicode U+20B9. These checks narrow down the cause; without the invoice HTML, CSS, font asset, request, and output PDF, the specific fault cannot be determined.
1. Check that the source contains the right character
First inspect the invoice data and rendered HTML. The Indian rupee sign is ₹ (U+20B9). It is distinct from ₨ (U+20A8), an older rupee sign. A visually similar character or a missing/incorrectly decoded value can make the issue look like a PDF rendering problem.
<span class="amount">₹1,250.00</span>
If your template, editor, or data pipeline has trouble preserving the literal character, try an HTML character reference:
<span class="amount">₹1,250.00</span>
<!-- Equivalent hexadecimal reference: -->
<span class="amount">₹1,250.00</span>
Open the rendered invoice HTML in a browser and inspect the amount. The browser should display ₹ before you investigate PDFShift. If it does not, fix the source data, template encoding, or HTML first.
2. Confirm the font file contains the rupee glyph
A CSS declaration naming a font does not guarantee that the actual font file contains U+20B9. Use a font whose character coverage includes that code point, and check that the invoice amount actually uses that font. A more specific selector or later CSS rule may be overriding your intended family.
PDFShift supports custom fonts through CSS supplied with the conversion request. Its documentation demonstrates the mechanism but does not certify that a particular example font contains the rupee glyph. Verify the font file you choose. See PDFShift’s custom fonts guide.
@font-face {
font-family: "InvoiceFont";
src: url("https://your-domain.example/fonts/invoice-font.woff2") format("woff2");
font-weight: 400;
font-style: normal;
}
.amount {
font-family: "InvoiceFont", sans-serif;
}
Replace the example URL with a font asset that your conversion environment can reach. Confirm the loaded font in the browser’s developer tools, then verify its glyph coverage with your font inspection tool or by rendering a test string containing ₹.
3. Make font delivery reliable
PDFShift recommends locally hosted or base64-encoded font files for faster, more consistent loading. External fonts may not have loaded when conversion starts, which can produce intermittent output. A font URL that works in your own browser can still fail from the conversion environment because of access restrictions, an expired signed URL, DNS or TLS problems, or a missing response.
- Prefer a reachable asset: ensure the font URL is publicly reachable by the conversion service or otherwise supplied using a supported method.
- Consider embedding the font: a base64 data URL avoids a separate external fetch, though it makes the CSS/request payload larger.
- Check the actual response: confirm the font request succeeds and returns a font file, not an HTML error page or redirect to an access-denied page.
- Keep the font rule targeted: apply the custom family to the amount or invoice body where needed, and avoid accidental overrides.
Consult PDFShift’s custom font instructions for the CSS parameter and supported request format.
4. Wait for asynchronous fonts before conversion
If the font loads asynchronously, PDFShift documents using wait_for to delay conversion until a condition is met. Its example checks document.fonts.ready. Follow the guide’s syntax for your request type and set the wait condition before conversion. See PDFShift’s wait guide.
// Function to add through the page or PDFShift's javascript setting:
function () {
return document.fonts.ready.then(function () {
return true;
});
}
Configure the request’s wait_for option to call the function using the format shown in PDFShift’s current documentation. Do not assume that adding JavaScript alone makes the converter wait; the wait condition must be configured as well. Font readiness means loading has settled, but it cannot make a font with no U+20B9 glyph display the symbol.
Waiting consumes conversion time. The cited PDFShift guide states timeouts of 30 seconds for free accounts and 100 seconds for premium accounts; check the current guide because vendor limits may change. Keep the font asset fast and the wait condition specific so that unrelated page activity does not use the remaining timeout budget.
5. Run the checks in order
- Inspect the invoice’s source data and rendered HTML. Confirm the amount contains U+20B9 or the equivalent character reference.
- Check that the browser renders ₹ before conversion.
- Inspect which font is applied to the amount and verify that its actual file contains U+20B9.
- Check the font request for failures, redirects, or access restrictions. Prefer a reachable local asset or an embedded font if external loading is unreliable.
- If the font is asynchronous, configure PDFShift to wait for
document.fonts.ready. - Convert again and inspect the resulting PDF. If the browser shows ₹ but the PDF does not, focus on the font actually available to the conversion environment and whether it finished loading in time.
This browser-versus-PDF comparison is a practical diagnostic inference from PDFShift’s font and wait guidance, not a vendor-prescribed test or a guaranteed root-cause result.
Common errors and fixes
| Symptom | Likely area to check | Fix |
|---|---|---|
| The symbol is already missing in the browser. | Template data, character encoding, or HTML. | Use U+20B9 (₹), or test ₹ / ₹; inspect the rendered text. |
| A box, blank space, or replacement character appears. | The selected font may lack the U+20B9 glyph. | Choose and verify a font file with rupee-sign coverage; confirm the amount uses it. |
| The symbol appears sometimes, but not on every conversion. | An external font may not have loaded before rendering. | Use a reachable local or base64 font and configure a font readiness wait. |
| The font works in a local browser but not in the PDF. | The conversion environment may not be able to fetch the asset, or may use different CSS/font rules. | Check the font URL response and applied family during conversion; remove access barriers and CSS overrides. |
| The conversion times out after adding a wait. | The font or another awaited condition may never become ready within the request’s remaining time. | Fix failed or slow asset requests, wait only for the needed condition, and check the current account timeout limit. |
| The output contains a different rupee-like character. | The source may use U+20A8 (₨) or another lookalike. | Inspect the code point and replace it with U+20B9 when the Indian rupee sign is intended. |
Reliability, performance, and cost considerations
- Reliability: a self-contained or reliably reachable font reduces dependence on third-party font delivery. A readiness wait addresses timing, not missing glyph coverage or incorrect source text.
- Performance: local or embedded fonts avoid some external-fetch variability. Embedding increases request size; waiting adds latency, so use the smallest suitable font asset and a specific readiness condition.
- Timeouts: budget time for page loading, font fetching, and conversion together. PDFShift’s documented limits can change; verify them against its current wait guide.
- Cost: the dossier provides no current per-conversion pricing to quote. Check PDFShift’s current plan details before estimating production invoice costs.
- Validation: keep a representative invoice fixture with amounts containing ₹ and inspect generated PDFs after changing fonts, CSS, or rendering settings.
Or skip the browser setup
ScreenshotNeo captures website pages as images or PDFs through one API request. It is useful when the task is capturing a rendered invoice page for review or sharing; it does not diagnose or repair a missing glyph in a PDFShift-generated PDF. See the ScreenshotNeo website and API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Replace the example target with a page you are authorized to capture. ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000.
Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.
FAQ
Is ₹ the same as the Indian rupee sign?
Yes. It is the decimal HTML character reference for U+20B9, the Indian rupee sign. The hexadecimal reference is ₹.
Will document.fonts.ready fix every missing symbol?
No. It helps ensure font loading has settled. The source still needs the correct character, and the loaded font still needs its glyph.
Can I use any font shown in a PDFShift example?
Do not assume so. Check the actual font file for U+20B9 coverage and confirm it is the font applied to the amount.
Does ScreenshotNeo fix a missing rupee glyph in a PDFShift invoice?
No. ScreenshotNeo captures web pages; the repair for a missing glyph is in the invoice’s text, font coverage, or PDFShift font-loading setup.


