How do I pass Remix.jsx file data to the liquid file?

Topic summary

A developer is building a Shopify Remix app and needs to pass data from .jsx files (stored in a Prisma database) to liquid template files in a theme extension. The app includes:

Current Setup:

  • Remix app with .jsx route files
  • Theme extension with liquid blocks for storefront UI
  • Data saved in app gets stored in Prisma database

Goal:

  • When data is saved in the .jsx file, automatically pass it to the corresponding liquid file

Implementation Details:

  • The .jsx file includes form controls: dropdown (theme selector), checkbox (rounded corners), and range slider (font size)
  • Uses React hooks (useState, useCallback, useEffect) with useLoaderData
  • The liquid file attempts to access settings via shop.metafields.custom_namespace.liquidData
  • Includes JavaScript to apply settings (e.g., background color based on theme)

Current Status:

  • Developer explicitly requests no “GPT answers” as they’ve already tried extensively
  • No solution found yet
  • One user inquired about updates but received no positive response
Summarized with AI on November 6. AI used: claude-sonnet-4-5-20250929.

I’ve built one Shopify Remix app. In the default app, there are the.jsx format files under the app > routes.

I’ve added a theme extension for the app’s embedded UI for the storefront.

Which is to build the folder in an app: extentions > extension name > blocks >.liquid

Currently, I’m adding data to the app, and it is stored in the Prisma database.

All I want is that when I save the .jsx file data in the app, it will also pass in a liquid file.

Don’t provide GPT answers. I’ve already tried my best for long.

This is my .jsx file.

//JSX File
export default function appearance() {
// Dropdown Event
  const theme = useLoaderData();
  const [selected, setSelected] = useState(theme.theme); // Ensure we're using the correct path
  const handleSelectChange = useCallback((value) => {
    setFormState((prevState) => ({
      ...prevState,
      theme: value
    }));
  }, []);

  const options = [
    { label: "Light", value: "light" },
    { label: "Dark", value: "dark" }
  ];

//Checkbox Event
    const initialData = useLoaderData();
const [checked, setChecked] = useState(initialData.rounded);

const handleCheck = useCallback((event) => {
  setChecked(event.target.checked);
}, []);

useEffect(() => {
  setChecked(initialData.rounded);
}, [initialData]);

//Range Slider Event
    const [rangeValue, setRangeValue] = useState(initialData.rangeValue);
    const handleChange = useCallback((event) => {
      setRangeValue(parseInt(event.target.value, 10));
    }, []);
  
    useEffect(() => {
      setRangeValue(initialData.rangeValue);
    }, [initialData]);

const liquidData = JSON.stringify(formState);

return (
<Form method="POST">
  
<TextField
        label="Test Field"
        name="test"
        value={formState?.test}
        onChange={(value) => setFormState({ ...formState, test: value })}
      />
<Select
        label="Theme"
        options={options}
        onChange={handleSelectChange}
        name="theme"
        value={formState?.theme}
      />
<input
        type="checkbox"
        checked={checked}
        onChange={handleCheck}
        name="rounded"
        value={checked.toString()}
      />
      Rounded corners</label>
<label>
Font Size
<input
  type="range"
  name="rangeValue"
  min="12"
  max="46"
  value={rangeValue}
  onChange={handleChange}
/>
</label>
</Form>
);}

This is my liquid file data

const appearanceSettings = {{ appearance_settings.value | json }};
  
  document.addEventListener('DOMContentLoaded', function() {
    // Use the appearanceSettings data in your JavaScript
    console.log(appearanceSettings);
    // Example: Apply the settings to your elements
    document.body.style.backgroundColor = appearanceSettings.theme === 'dark' ? '#000' : '#fff';
  });
{% assign appearance_settings = shop.metafields.custom_namespace.liquidData %}

{% if appearance_settings %}
  # Appearance Settings
  
    - Theme: {{ appearance_settings.theme }}

    - Test: {{ appearance_settings.test }}

    - Rounded: {{ appearance_settings.rounded }}

    - Font Size: {{ appearance_settings.rangeValue }}

    - Color: {{ appearance_settings.color | json }}
  

{% else %}
  

Loading...

{% endif %}

any update on this @anupam1607 ?

No @miteshbhagwant :neutral_face: