1

I have a block in which I'd like to display a link based on the site url. So for example, when the user enters "Futuristic", the link will display as https://my-site.com/futuristic/

I've looked at REST API /settings/ endpoint, which is supposed to include a url field, but it doesn't (at least on the two different sites I tried). Perhaps this is because I've got WP set up as multisite. There still should be a way to access the current site's url I'm sure.

I've looked into what wp.data.select() can provide in the various namespaces, but I don't see anything that would include the site url.

I tried looking at output of wp.data.select('core').getSite() (see Hardeep's suggestion), but mine has no url property and looks like this:

{ 
  date_format: "F j, Y"
  default_category: 1
  default_comment_status: "open"
​  default_ping_status: "open"
​  default_post_format: "0"
​  description: ""
​  language: ""
​  posts_per_page: 10
​  start_of_week: 0
​  time_format: "g:i a"
​  timezone: "America/New_York"
​  title: "The Name of My Site"
​  use_smilies: true
}

I suspect the difference has to do with Multisite being enabled, but not sure.

2
  • There is no getSite selector in core namespace. I even tried searching Gutenberg's github.
    – Lovor
    Commented Nov 2, 2022 at 21:54
  • 1
    @Lovor This is not correct. Open your block editor for a post. In your browser console type wp.data.select('core').getSite() and you should see the results as described above.
    – JakeParis
    Commented Nov 3, 2022 at 1:27

3 Answers 3

3

Perhaps this is because I've got WP set up as multisite.

Yes, that's right, WordPress disables the siteurl (and also admin_email) settings on a Multisite — see register_initial_settings() for the source.

And I don't know why they disable those (two) settings, but you can explicitly enable them like so for the url/siteurl setting, which for example, would go in the theme's functions.php file:

// I copied this from the source..
register_setting(
    'general',
    'siteurl',
    array(
        'show_in_rest' => array(
            'name'   => 'url',
            'schema' => array(
                'format' => 'uri',
            ),
        ),
        'type'         => 'string',
        'description'  => __( 'Site URL.' ),
    )
);

Tried & tested working with WordPress 5.6.1 Multisite.

And also, wp.data.select( 'core' ).getSite() uses the Settings endpoint, so it's normal that the url property is missing by default on a Multisite.

Apart from that, getSite() caches the API results, so you'd need to reload the post editing screen/page in order for getSite() to give you the correct result, i.e. with the url property.

2
  • How did you find about this getSite selector? I cannot find it in documentation, nor in Gutenberg code in repository. However, it does work. Can you point to code where it is added?
    – Lovor
    Commented Jan 1, 2023 at 16:55
  • @Lovor, sorry for the late reply, but it's nice to know you already found it 🙂
    – Sally CJ
    Commented Jan 12, 2023 at 5:42
0

You can use wp_localize_script to pass anything you want, including site URL, to the editor as a global variable:

wp_localize_script(
    'script_name',
    'my_data',
    [
        'siteUrl' => get_site_url()
    ]
);

And then you can get it in the editor from window.my_data.siteUrl variable. Here script_name will be the script that you're enqueuing to the editor.

If you want to use the Data API, you can use wp.data.select( 'core' ).getSite(); and once the promise has resolved, you can use the URL property.

enter image description here

4
  • Thank you for that. That is one way, but I thought there might be a more built-in way. By the way, it is preferred to use wp_add_inline_script() instead of wp_localize_script()
    – JakeParis
    Commented Feb 10, 2021 at 1:31
  • If you want to use Data API then you can use the wp.data.select( 'core' ).getSite();, once the promise resolves, you can use the URL property to get the website URL. Commented Feb 10, 2021 at 12:06
  • Thank you. My getSite() output is different than what you got. I added it to my question.
    – JakeParis
    Commented Feb 10, 2021 at 15:08
  • Unfortunately, there's no better way, at least in my knowledge, that will work. :( Commented Feb 10, 2021 at 19:15
-1

There is only this post give me the best answer and I do some research on my own.

I found a way but doesn't know it's a great method or not. But I will share it here.

import { useSelect } from '@wordpress/data'

const siteUrl = useSelect(select => {
    const site = select('core').getSite();
    return site && site.url;
});

and you can pass {siteUrl} anywhere you want to retrive the site url in edit.js.

don't know why

return site && site.url;

worked.

I ask chatgpt and it work perfectly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.