You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
And they are supposed to be correctly parsed and should open in new browser tab on users click on webpage
however this is not happening, links are showing as undefined on webpage and i am seeing this error in console > F12
Error paragraph",raw:a,text:a,tokens:[{type:"text",raw:a,text:a,escaped:!0}]}):n+=a;continue}default:{const o='Token with "'+c.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}parseInline(e,t=this.renderer){var r,s;let n="";for(let l=0;l<e.length;l++){const i=e[l];if((s=(r=this.options.extensions)==null?void 0:r.renderers)!=null&&s[i.type]){const o=this.options.extensions.renderers[i.type].call({parser:this},i);if(o!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(i.type)){n+=o||"";continue}}const c=i;switch(c.type){case"escape":{n+=t.text(c);break}case"html":{n+=t.html(c);break}case"link":{n+=t.link(c);break}case"image":{n+=t.image(c);break}case"strong":{n+=t.strong(c);break}case"em":{n+=t.em(c);break}case"codespan":{n+=t.codespan(c);break}case"br":{n+=t.br(c);break}case"del":{n+=t.del(c);break}case"text":{n+=t.text(c);break}default:{const o='Token with "'+c.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}}class L{constructor(e){b(this,"options");b(this,"block");this.options=e||z}preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}provideLexer(){return this.block?$.lex:$.lexInline}provideParser(){return this.block?R.parse:R.parseInline}}b(L,"passThroughHooks",new Set(["preprocess","postprocess","processAllTokens"]));class it{constructor(...e){b(this,"defaults",H());b(this,"options",this.setOptions);b(this,"parse",this.parseMarkdown(!0));b(this,"parseInline",this.parseMarkdown(!1));b(this,"Parser",R);b(this,"Renderer",v);b(this,"TextRenderer",V);b(this,"Lexer",$);b(this,"Tokenizer",E);b(this,"Hooks",L);this.use(...e)}walkTokens(e,t){var r,s;let n=[];for(const l of e)switch(n=n.concat(t.call(this,l)),l.type){case"table":{const i=l;for(const c of i.header)n=n.concat(this.walkTokens(c.tokens,t));for(const c of i.rows)for(const o of c)n=n.concat(this.walkTokens(o.tokens,t));break}case"list":{const i=l;n=n.concat(this.walkTokens(i.items,t));break}default:{const i=l;(s=(r=this.defaults.extensions)==null?void 0:r.childTokens)!=null&&s[i.type]?this.defaults.extensions.childTokens[i.type].forEach(c=>{const o=i[c].flat(1/0);n=n.concat(this.walkTokens(o,t))}):i.tokens&&(n=n.concat(this.walkTokens(i.tokens,t)))}}return n}use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{const r={...n};if(r.async=this.defaults.async||r.async||!1,n.extensions&&(n.extensions.forEach(s=>{if(!s.name)throw new Error("extension name required");if("renderer"in s){const l=t.renderers[s.name];l?t.renderers[s.name]=function(...i){let c=s.renderer.apply(this,i);return c===!1&&(c=l.apply(this,i)),c}:t.renderers[s.name]=s.renderer}if("tokenizer"in s){if(!s.level||s.level!=="block"&&s.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");const l=t[s.level];l?l.unshift(s.tokenizer):t[s.level]=[s.tokenizer],s.start&&(s.level==="block"?t.startBlock?t.startBlock.push(s.start):t.startBlock=[s.start]:s.level==="inline"&&(t.startInline?t.startInline.push(s.start):t.startInline=[s.start]))}"childTokens"in s&&s.childTokens&&(t.childTokens[s.name]=s.childTokens)}),r.extensions=t),n.renderer){const s=this.defaults.renderer||new v(this.defaults);for(const l in n.renderer){if(!(l in s))throw new Error(renderer '${l}' does not exist);if(["options","parser"].includes(l))continue;const i=l,c=n.renderer[i],o=s[i];s[i]=(...a)=>{let u=c.apply(s,a);return u===!1&&(u=o.apply(s,a)),u||""}}r.renderer=s}if(n.tokenizer){const s=this.defaults.tokenizer||new E(this.defaults);for(const l in n.tokenizer){if(!(l in s))throw new Error(tokenizer '${l}' does not exist);if(["options","rules","lexer"].includes(l))continue;const i=l,c=n.tokenizer[i],o=s[i];s[i]=(...a)=>{let u=c.apply(s,a);return u===!1&&(u=o.apply(s,a)),u}}r.tokenizer=s}if(n.hooks){const s=this.defaults.hooks||new L;for(const l in n.hooks){if(!(l in s))throw new Error(hook '${l}' does not exist);if(["options","block"].includes(l))continue;const i=l,c=n.hooks[i],o=s[i];L.passThroughHooks.has(l)?s[i]=a=>{if(this.defaults.async)return Promise.resolve(c.call(s,a)).then(p=>o.call(s,p));const u=c.call(s,a);return o.call(s,u)}:s[i]=(...a)=>{let u=c.apply(s,a);return u===!1&&(u=o.apply(s,a)),u}}r.hooks=s}if(n.walkTokens){const s=this.defaults.walkTokens,l=n.walkTokens;r.walkTokens=function(i){let c=[];return c.push(l.call(this,i)),s&&(c=c.concat(s.call(this,i))),c}}this.defaults={...this.defaults,...r}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return $.lex(e,t??this.defaults)}parser(e,t){return R.parse(e,t??this.defaults)}parseMarkdown(e){return(n,r)=>{const s={...r},l={...this.defaults,...s},i=this.onError(!!l.silent,!!l.async);if(this.defaults.async===!0&&s.async===!1)return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof n>"u"||n===null)return i(new Error("marked(): input parameter is undefined or null"));if(typeof n!="string")return i(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));l.hooks&&(l.hooks.options=l,l.hooks.block=e);const c=l.hooks?l.hooks.provideLexer():e?$.lex:$.lexInline,o=l.hooks?l.hooks.provideParser():e?R.parse:R.parseInline;if(l.async)return Promise.resolve(l.hooks?l.hooks.preprocess(n):n).then(a=>c(a,l)).then(a=>l.hooks?l.hooks.processAllTokens(a):a).then(a=>l.walkTokens?Promise.all(this.walkTokens(a,l.walkTokens)).then(()=>a):a).then(a=>o(a,l)).then(a=>l.hooks?l.hooks.postprocess(a):a).catch(i);try{l.hooks&&(n=l.hooks.preprocess(n));let a=c(n,l);l.hooks&&(a=l.hooks.processAllTokens(a)),l.walkTokens&&this.walkTokens(a,l.walkTokens);let u=o(a,l);return l.hooks&&(u=l.hooks.postprocess(u)),u}catch(a){return i(a)}}}onError(e,t){return n=>{if(n.message+=
Please report this to https://github.com/markedjs/marked.`,e){const r="
found workaround, simply put link in html format in md file itself, example: Learn more about AI <a href="https://officialai.io/" target="_blank" rel="noopener noreferrer">Learn more about AI</a>
Marked version:
marked@15.0.7
Describe the bug
I have a url links in my blog .md file, example:
$ cat notes.md | grep https
🔗 Learn more about GPT-5
🎨 Try MidJourney
And they are supposed to be correctly parsed and should open in new browser tab on users click on webpage
however this is not happening, links are showing as undefined on webpage and i am seeing this error in console > F12
Error
paragraph",raw:a,text:a,tokens:[{type:"text",raw:a,text:a,escaped:!0}]}):n+=a;continue}default:{const o='Token with "'+c.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}parseInline(e,t=this.renderer){var r,s;let n="";for(let l=0;l<e.length;l++){const i=e[l];if((s=(r=this.options.extensions)==null?void 0:r.renderers)!=null&&s[i.type]){const o=this.options.extensions.renderers[i.type].call({parser:this},i);if(o!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(i.type)){n+=o||"";continue}}const c=i;switch(c.type){case"escape":{n+=t.text(c);break}case"html":{n+=t.html(c);break}case"link":{n+=t.link(c);break}case"image":{n+=t.image(c);break}case"strong":{n+=t.strong(c);break}case"em":{n+=t.em(c);break}case"codespan":{n+=t.codespan(c);break}case"br":{n+=t.br(c);break}case"del":{n+=t.del(c);break}case"text":{n+=t.text(c);break}default:{const o='Token with "'+c.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}}class L{constructor(e){b(this,"options");b(this,"block");this.options=e||z}preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}provideLexer(){return this.block?$.lex:$.lexInline}provideParser(){return this.block?R.parse:R.parseInline}}b(L,"passThroughHooks",new Set(["preprocess","postprocess","processAllTokens"]));class it{constructor(...e){b(this,"defaults",H());b(this,"options",this.setOptions);b(this,"parse",this.parseMarkdown(!0));b(this,"parseInline",this.parseMarkdown(!1));b(this,"Parser",R);b(this,"Renderer",v);b(this,"TextRenderer",V);b(this,"Lexer",$);b(this,"Tokenizer",E);b(this,"Hooks",L);this.use(...e)}walkTokens(e,t){var r,s;let n=[];for(const l of e)switch(n=n.concat(t.call(this,l)),l.type){case"table":{const i=l;for(const c of i.header)n=n.concat(this.walkTokens(c.tokens,t));for(const c of i.rows)for(const o of c)n=n.concat(this.walkTokens(o.tokens,t));break}case"list":{const i=l;n=n.concat(this.walkTokens(i.items,t));break}default:{const i=l;(s=(r=this.defaults.extensions)==null?void 0:r.childTokens)!=null&&s[i.type]?this.defaults.extensions.childTokens[i.type].forEach(c=>{const o=i[c].flat(1/0);n=n.concat(this.walkTokens(o,t))}):i.tokens&&(n=n.concat(this.walkTokens(i.tokens,t)))}}return n}use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{const r={...n};if(r.async=this.defaults.async||r.async||!1,n.extensions&&(n.extensions.forEach(s=>{if(!s.name)throw new Error("extension name required");if("renderer"in s){const l=t.renderers[s.name];l?t.renderers[s.name]=function(...i){let c=s.renderer.apply(this,i);return c===!1&&(c=l.apply(this,i)),c}:t.renderers[s.name]=s.renderer}if("tokenizer"in s){if(!s.level||s.level!=="block"&&s.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");const l=t[s.level];l?l.unshift(s.tokenizer):t[s.level]=[s.tokenizer],s.start&&(s.level==="block"?t.startBlock?t.startBlock.push(s.start):t.startBlock=[s.start]:s.level==="inline"&&(t.startInline?t.startInline.push(s.start):t.startInline=[s.start]))}"childTokens"in s&&s.childTokens&&(t.childTokens[s.name]=s.childTokens)}),r.extensions=t),n.renderer){const s=this.defaults.renderer||new v(this.defaults);for(const l in n.renderer){if(!(l in s))throw new Error(
renderer '${l}' does not exist);if(["options","parser"].includes(l))continue;const i=l,c=n.renderer[i],o=s[i];s[i]=(...a)=>{let u=c.apply(s,a);return u===!1&&(u=o.apply(s,a)),u||""}}r.renderer=s}if(n.tokenizer){const s=this.defaults.tokenizer||new E(this.defaults);for(const l in n.tokenizer){if(!(l in s))throw new Error(
tokenizer '${l}' does not exist);if(["options","rules","lexer"].includes(l))continue;const i=l,c=n.tokenizer[i],o=s[i];s[i]=(...a)=>{let u=c.apply(s,a);return u===!1&&(u=o.apply(s,a)),u}}r.tokenizer=s}if(n.hooks){const s=this.defaults.hooks||new L;for(const l in n.hooks){if(!(l in s))throw new Error(
hook '${l}' does not exist);if(["options","block"].includes(l))continue;const i=l,c=n.hooks[i],o=s[i];L.passThroughHooks.has(l)?s[i]=a=>{if(this.defaults.async)return Promise.resolve(c.call(s,a)).then(p=>o.call(s,p));const u=c.call(s,a);return o.call(s,u)}:s[i]=(...a)=>{let u=c.apply(s,a);return u===!1&&(u=o.apply(s,a)),u}}r.hooks=s}if(n.walkTokens){const s=this.defaults.walkTokens,l=n.walkTokens;r.walkTokens=function(i){let c=[];return c.push(l.call(this,i)),s&&(c=c.concat(s.call(this,i))),c}}this.defaults={...this.defaults,...r}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return $.lex(e,t??this.defaults)}parser(e,t){return R.parse(e,t??this.defaults)}parseMarkdown(e){return(n,r)=>{const s={...r},l={...this.defaults,...s},i=this.onError(!!l.silent,!!l.async);if(this.defaults.async===!0&&s.async===!1)return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof n>"u"||n===null)return i(new Error("marked(): input parameter is undefined or null"));if(typeof n!="string")return i(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));l.hooks&&(l.hooks.options=l,l.hooks.block=e);const c=l.hooks?l.hooks.provideLexer():e?$.lex:$.lexInline,o=l.hooks?l.hooks.provideParser():e?R.parse:R.parseInline;if(l.async)return Promise.resolve(l.hooks?l.hooks.preprocess(n):n).then(a=>c(a,l)).then(a=>l.hooks?l.hooks.processAllTokens(a):a).then(a=>l.walkTokens?Promise.all(this.walkTokens(a,l.walkTokens)).then(()=>a):a).then(a=>o(a,l)).then(a=>l.hooks?l.hooks.postprocess(a):a).catch(i);try{l.hooks&&(n=l.hooks.preprocess(n));let a=c(n,l);l.hooks&&(a=l.hooks.processAllTokens(a)),l.walkTokens&&this.walkTokens(a,l.walkTokens);let u=o(a,l);return l.hooks&&(u=l.hooks.postprocess(u)),u}catch(a){return i(a)}}}onError(e,t){return n=>{if(n.message+=
Please report this to https://github.com/markedjs/marked.`,e){const r="
An error occurred:
";return t?Promise.resolve(r):r}if(t)return Promise.reject(n);throw n}}}const T=new it;function d(h,e){return T.parse(h,e)}d.options=d.setOptions=function(h){return T.setOptions(h),d.defaults=T.defaults,ae(d.defaults),d};d.getDefaults=H;d.defaults=z;d.use=function(...h){return T.use(...h),d.defaults=T.defaults,ae(d.defaults),d};d.walkTokens=function(h,e){return T.walkTokens(h,e)};d.parseInline=T.parseInline;d.Parser=R;d.parser=R.parse;d.Renderer=v;d.TextRenderer=V;d.Lexer=$;d.lexer=$.lex;d.Tokenizer=E;d.Hooks=L;d.parse=d;d.options;d.setOptions;d.use;d.walkTokens;d.parseInline;R.parse;$.lex;function at(){const{slug:h}=$e(),[e,t]=M.useState(null),[n,r]=M.useState([]),s=new d.Renderer;if(s.link=(i,c,o)=>{if(!i||typeof i!="string")return console.warn("Invalid href detected:",i),o;const a=c?title="${c}"
:"";return<a href="${i.trim()}" ${a} target="_blank" rel="noopener noreferrer">${o}</a>
},M.useEffect(()=>{(async()=>{try{const o=await(await fetch("/data/blogs.json")).json();r(o);const a=o.find(x=>x.slug===h);if(!a){t(null);return}const p=await(await fetch(/blogs/${h}.md
)).text();console.log("Raw Markdown Content:",p);const g=p.replace(/^---[\s\S]*?---/,"").trim();console.log("Cleaned Markdown Content:",g);let m=d(g,{renderer:s});console.log("Generated HTML from Markdown:",m),m=m.replace(/<a /g,'<a target="_blank" rel="noopener noreferrer" '),t({...a,content:m})}catch(c){console.error("Error fetching blog content:",c)}})()},[h]),e===null)return f.jsx("p",{className:"text-center mt-10 text-gray-500",children:"Loading blog post..."});if(!e)return f.jsx("p",{className:"text-center mt-10 text-red-500",children:"Blog post not found."});console.log("Final Blog Content to Render:",e.content);const l={"@context":"https://schema.org","@type":"Article",headline:e.title,url:`https://officialai.io/blog/${e.slug}`,author:{"@type":"Person",name:e.author},datePublished:`${e.date}T12:00:00Z`,dateModified:`${e.date}T12:00:00Z`,image:e.image,publisher:{"@type":"Organization",name:"OfficialAI.io",logo:{"@type":"ImageObject",url:"https://officialai.io/logo.png"}},description:e.description,mainEntityOfPage:{"@type":"WebPage","@id":`https://officialai.io/blog/${e.slug}`}};return f.jsxs("div",{className:"max-w-3xl mx-auto p-6",children:[f.jsxs(Re,{children:[f.jsxs("title",{children:[e.title," | OfficialAI.io"]}),f.jsx("meta",{name:"description",content:e.description}),f.jsx("meta",{name:"keywords",content:e.tags.join(", ")}),f.jsx("meta",{name:"author",content:e.author}),f.jsx("meta",{property:"og:title",content:e.title}),f.jsx("meta",{property:"og:description",content:e.description}),f.jsx("meta",{property:"og:image",content:e.image}),f.jsx("meta",{property:"og:url",content:https://officialai.io/blog/${e.slug}
}),f.jsx("meta",{property:"og:type",content:"article"}),f.jsx("meta",{name:"twitter:card",content:"summary_large_image"}),f.jsx("meta",{name:"twitter:title",content:e.title}),f.jsx("meta",{name:"twitter:description",content:e.description}),f.jsx("meta",{name:"twitter:image",content:e.image}),f.jsx("script",{type:"application/ld+json",children:JSON.stringify(l)})]}),f.jsx("img",{src:e.image,alt:e.title,className:"w-full h-60 object-cover rounded-lg mb-4"}),f.jsx("h1",{className:"text-3xl font-bold mb-2",children:e.title}),f.jsxs("p",{className:"text-gray-500 text-sm",children:["By ",e.author," • ",e.date," • ",e.reading_time]}),f.jsx("p",{className:"text-gray-600 mb-4",children:e.description}),f.jsx("div",{className:"mt-2 flex flex-wrap gap-2",children:e.tags.map((i,c)=>f.jsx("span",{className:"bg-blue-100 text-blue-600 text-xs px-2 py-1 rounded-full",children:i},c))}),f.jsx("hr",{className:"my-4"}),f.jsx("div",{className:"blog-container",children:f.jsx("div",{className:"blog-content prose max-w-none",dangerouslySetInnerHTML:{__html:e.content}})}),f.jsxs("div",{className:"mt-6 flex justify-between",children:[n.findIndex(i=>i.slug===h)>0&&f.jsxs(O,{to:/blog/${n[n.findIndex(i=>i.slug===h)-1].slug}
,className:"text-blue-500 hover:underline",children:["← ",n[n.findIndex(i=>i.slug===h)-1].title]}),f.jsx(O,{to:"/blog",className:"text-blue-500 hover:underline",children:"Return to Blog"}),n.findIndex(i=>i.slug===h)<n.length-1&&f.jsxs(O,{to:/blog/${n[n.findIndex(i=>i.slug===h)+1].slug}
,className:"text-blue-500 hover:underline",children:[n[n.findIndex(i=>i.slug===h)+1].title," →"]})]})]})}export{at as default};`
This is my code :
` import { marked } from "marked";
useEffect(() => {
const fetchData = async () => {
try {
// ✅ Fetch blog metadata
const response = await fetch("/data/blogs.json");
const data = await response.json();
setBlogs(data);
Expected behavior
I want URLs to open in new tab when user click on link in my blog.
The text was updated successfully, but these errors were encountered: