Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Can't access to media in API responses

default discord avatar
aliqqaelast year
15

Hello, I am trying to make the last bits for my blog, and i am trying to get images in my posts so it's nicer.



However, I tried many ways and I cannot find a solution that would simply work.



Basically, my content-type Article looks like this in Astro for this version :


    <header class="story__header -vertical">
        <!-- article header  -->
    </header>
    <section class="section">
        <main class="main">
            <article class="article">
                <RichText richText={ content } />
            </article>
        </main>
    </section>


My RichText Component, that I found in september in a blog article looks like this (isn't there a better way ?)


{
    content.richText.map((node) =>
        Text.isText(node) ? (
                <Fragment>
                        <!-- some bits about bold and stuff -->
                </Fragment>
            ) : (
                <Fragment>
                     
                        <!-- this is where i try to include images -->
                        { node.type === "img" && (
                                <img 
                                        src={ escapeHTML(node.url) } 
                                        alt={ escapeHTML(node.children) } }
                                />
                        )}
                        {!node.type && <p>{<Astro.self richText={ node.children } />}</p>}
                </Fragment>
            )
        )
    }


I know there is a way but i tried everything I could think about to get the images in articles. For now it's still Astro's templating system.



## The most important part:



My Payload response looks like this


{

    "id": "6532b97610b7bdb6a1c7e6b9",
    "title": "Test article",
    "slug": "lorem-ipsum-dolor",
    "categories": "Journal",

"tags": [

    "Site web"

],
"article": [

{

"children": [

        {
            "text": "Oui juste un essai"
        }
    ]

},
{

"children": [

    {
        "text": ""
    }

],
"relationTo": "media",
"type": "upload",

    "value": {
        "id": "652b210331b92ebd6ad6f0be",
        "alt": "Fenêtre de Powershell Windows qui liste toutes mes tentatives infructueuses pour créer un site web",
        "filename": "ls-sur-terminal.png",
        "mimeType": "image/png",
        "filesize": 30414,
        "width": 942,
        "height": 480,
        "createdAt": "2023-10-14T23:15:15.176Z",
        "updatedAt": "2023-10-14T23:15:15.176Z",
        "url": "/media/ls-sur-terminal.png"
    }

},
{

"children": [

                {
                    "text": ""
                }
            ]
        }
    ],
    "_status": "published",
    "createdAt": "2023-10-20T17:31:34.591Z",
    "updatedAt": "2023-10-20T22:52:56.631Z"

}
  • default discord avatar
    diesieben07last year

    You need to change your Astro template. Currently you're checking for

    node.type === "img"

    , which never happens. You need to check for

    node.type === "upload"

    and then adjust the template to get the URL and alt text in the correct way based on how the Payload response looks.

  • default discord avatar
    aliqqaelast year

    I get it, i tried that too but the whole file look like this, so it felt like it's based on HTML nodes :



    Also yeah it gives a lot of errors and i hate it. I just need that part to work, and i'll refactor everything into react once that version is published

    image.png
  • default discord avatar
    diesieben07last year

    Yeah, unfortunately the default Slate typescript types are very barebones. You are supposed to define your own element types:

    https://docs.slatejs.org/concepts/12-typescript
  • default discord avatar
    aliqqaelast year

    even in my front-end ?



    { node.type === "upload" && (
        <img 
            src={ console.log(node) } 
            alt={ escapeHTML(node.alt) }
        />
    )}


    I am getting somewhere with this, i receive a

    [Object object]


    I guess i'll take a break and rewrite this in a more elegant way



    After some thinking, what I don't understand in Slate docs and articles on the internet, it's the mention for the Editor. The Editor is in Payload, what I want to do is to render Elements in my Article. I don't need an Editor in Astro.



    And find how to get the image from the API Response

  • For your src, you would use

    node.value.url


    Also, you are console logging inside your src, which is not helpful for you. You would want to console log outside of that

  • default discord avatar
    aliqqaelast year

    Yes, i tried everywhere 😭



    i am trying this



    mmh it returns undefined



    I wish i could just see the structure in it



    another code example to how to get the images i try to get from Slate



    20:46:55 [astro] reload D:/Projets/Personnels/palingenae.be/2023/front-end/src/pages/blog/[slug].astro
    [
      { children: [ [Object] ] },
      {
        children: [ [Object] ],
        relationTo: 'media',
        type: 'upload',
        value: {
          id: '652b210331b92ebd6ad6f0be',
          alt: 'Fenêtre de Powershell Windows qui liste toutes mes tentatives infructueuses pour créer un site web',      
          filename: 'ls-sur-terminal.png',
          mimeType: 'image/png',
          filesize: 30414,
          width: 942,
          height: 480,
          createdAt: '2023-10-14T23:15:15.176Z',
          updatedAt: '2023-10-14T23:15:15.176Z',
          url: '/media/ls-sur-terminal.png'
        }
      },
      { children: [ [Object] ] }
    ]


    That's my

    console.log(content)

    in

    [slug].astro
    image.png
  • default discord avatar
    dr_mintlast year

    That's looking alright, there is an url here, you still have problems with the images?

  • default discord avatar
    aliqqaelast year

    Yes, whatever I do, it's either

    undefined

    or

    [Object object]

    . For the first i guess that the properties are not there. For the latter it feels like i have to go further, but Astro crashed because the value isn't right.



    At this rate, i don't know what i forgot

  • Can you show where you are rendering an image

  • default discord avatar
    aliqqaelast year

    Here @jarrod_not_jared, I want to integrate those images with SlateJS


    Node "upload", as of now



    And here is where i want to call SlateJS RichText rendering



    i fumble around to read the Media's URL

    image.png
    image.png
  • When your node.type is upload, it does not seem right that you are using node.element.path for the src



    Wouldn’t it be what I said above?

    node.value.url

    ?

  • default discord avatar
    aliqqaelast year

    i tried, it returns

    undefined


    And I think that the issue is that i copy pasted this



    without understanding what it was about



    but even after reading that code it does not makes sense, because it is supposed to work



    and even if I go to upper layer,

    article/[slug].astro

    , i cannot get the image



    So now my question, before going to sleep (i am GMT+2), what is the most common way to read images from nodes that come from SlateJS ?



    Because I did read the documentation, and unless i couldn't wrap my head about something important, i didn't see what would help me render an image in my front-end



    :think:
  • default discord avatar
    dr_mintlast year

    Looking at the data,

    content

    is an array, its second element is an object with a property type of value "upload". It also has a property value, and value.url looks like a valid url.


    In

    [slug].astro

    if you write the following instead of using RichText:


    {content.map((node) => <p>{node.type}</p>)}

    I would expect the result on your webpage to be something like


    undefined
    upload
    undefined

    Now let's change the function a bit:


    content.map((node) => {
        if (node.type === "upload") {
            return <p>{node.value.url}</p>
        }
        return <p>Not an upload node</p>
    });

    This time I would expect the result to be:


    Not an upload node
    /media/ls-sur-terminal.png
    Not an upload node

    If so, instead of returning the url in paragraph, try returning an img tag with its src set as the url:


    content.map((node) => {
        if (node.type === "upload") {
            return <img src={node.type.url} />
        }
        return <p>Not a upload node</p>
    });

    It should display the image. If not, it means your web server is not set up to serve the

    media

    folder. But that's another story, let me know how these steps go first.

  • default discord avatar
    aliqqaelast year

    Thanks I’ll try this



    I was so focused to make it work that i forgot it was an array



    Thanks, i was tunnel visioned at the end



    I have been near the solution well earlier



    !solved



    ## My solution



        { node.type === "upload" && (
            <img src={escapeHTML(`${import.meta.env.API_URL}${node.value.url}`)} alt={escapeHTML(node.value.alt)}/>
        )}


    So,

    object.map()

    was already occurring well higher, so i didn't need to do anything about it.


    Another reason there was "

    undefined

    ", it was because it needed an absolute path, the whole url to the image, the other simplest part I didn't think about.



    Also, it motivates me to rewrite that

    RichText

    component because it's ugly and all red because of typing errors.



    Thanks for your time @jarrod_not_jared, @dr_mint, @diesieben07

  • default discord avatar
    dr_mintlast year

    Glad it helped 👍

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.